diff options
-rw-r--r-- | include/llvm/ADT/Hashing.h | 4 | ||||
-rw-r--r-- | include/llvm/Support/type_traits.h | 18 | ||||
-rw-r--r-- | unittests/ADT/HashingTest.cpp | 20 |
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; } |