aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/ADT/Hashing.h4
-rw-r--r--include/llvm/Support/type_traits.h18
-rw-r--r--unittests/ADT/HashingTest.cpp20
3 files changed, 22 insertions, 20 deletions
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index 1b0e669..7fbe5bb 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -357,8 +357,8 @@ template <typename T> struct is_hashable_data
template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
: integral_constant<bool, (is_hashable_data<T>::value &&
is_hashable_data<U>::value &&
- !is_alignment_padded<std::pair<T, U> >::value &&
- !is_pod_pair_padded<T, U>::value)> {};
+ (sizeof(T) + sizeof(U)) ==
+ sizeof(std::pair<T, U>))> {};
/// \brief Helper to get the hashable data representation for a type.
/// This variant is enabled when the type itself can be used.
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index a10d83c..85d90b1 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -126,24 +126,6 @@ struct is_integral : is_integral_impl<T> {};
template <typename T> struct is_pointer : false_type {};
template <typename T> struct is_pointer<T*> : true_type {};
-/// \brief Metafunction to compute whether a type requires alignment padding.
-/// When true, an object of this type will have padding bytes inside its
-/// 'sizeof' bytes.
-template <typename T> class is_alignment_padded {
- struct pod_size_tester { T t; char c; };
-public:
- enum { value = offsetof(pod_size_tester, c) != sizeof(T) };
-};
-
-/// \brief Metafunction to determine whether an adjacent pair of two types will
-/// require padding between them due to alignment.
-template <typename T, typename U> class is_pod_pair_padded {
- struct pod_pair { T t; U u; };
- struct pod_char_pair { T t; char c; };
-public:
- enum { value = offsetof(pod_pair, u) != offsetof(pod_char_pair, c) };
-};
-
// enable_if_c - Enable/disable a template based on a metafunction
template<bool Cond, typename T = void>
diff --git a/unittests/ADT/HashingTest.cpp b/unittests/ADT/HashingTest.cpp
index a12cf90..449b6af 100644
--- a/unittests/ADT/HashingTest.cpp
+++ b/unittests/ADT/HashingTest.cpp
@@ -42,6 +42,16 @@ using namespace llvm;
namespace {
+struct NonPOD {
+ uint64_t x, y;
+ NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
+ ~NonPOD() {}
+ friend hash_code hash_value(const NonPOD &obj) {
+ return hash_combine(obj.x, obj.y);
+ }
+};
+
+
TEST(HashingTest, HashValueBasicTest) {
int x = 42, y = 43, c = 'x';
void *p = 0;
@@ -73,6 +83,16 @@ TEST(HashingTest, HashValueBasicTest) {
hash_value(std::make_pair(42, std::make_pair(43, 44))));
EXPECT_EQ(hash_value(std::make_pair(42, std::make_pair(43, 44))),
hash_value(std::make_pair(std::make_pair(42, 43), 44)));
+
+ // Ensure that pairs which have padding bytes *inside* them don't get treated
+ // this way.
+ EXPECT_EQ(hash_combine('0', hash_combine(1ull, '2')),
+ hash_value(std::make_pair('0', std::make_pair(1ull, '2'))));
+
+ // Ensure that non-POD pairs don't explode the traits used.
+ NonPOD obj1(1, 2), obj2(3, 4), obj3(5, 6);
+ EXPECT_EQ(hash_combine(obj1, hash_combine(obj2, obj3)),
+ hash_value(std::make_pair(obj1, std::make_pair(obj2, obj3))));
}
template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }