Index: include/llvm/ADT/DenseMap.h =================================================================== --- include/llvm/ADT/DenseMap.h +++ include/llvm/ADT/DenseMap.h @@ -146,6 +146,10 @@ } const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); + + LLVM_VERIFY_ISPODLIKE_CONSISTENCY(KeyT); + LLVM_VERIFY_ISPODLIKE_CONSISTENCY(ValueT); + if (isPodLike::value && isPodLike::value) { // Use a simpler loop when these are trivial types. for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) Index: include/llvm/ADT/Optional.h =================================================================== --- include/llvm/ADT/Optional.h +++ include/llvm/ADT/Optional.h @@ -130,6 +130,7 @@ template class Optional { optional_detail::OptionalStorage::value> Storage; + LLVM_VERIFY_ISPODLIKE_CONSISTENCY(T); public: using value_type = T; @@ -202,11 +203,6 @@ #endif }; -template struct isPodLike> { - // An Optional is pod-like if T is. - static const bool value = isPodLike::value; -}; - template bool operator==(const Optional &X, const Optional &Y) { if (X && Y) Index: include/llvm/ADT/SmallVector.h =================================================================== --- include/llvm/ADT/SmallVector.h +++ include/llvm/ADT/SmallVector.h @@ -321,6 +321,8 @@ /// reduce code duplication based on the SmallVector 'N' template parameter. template class SmallVectorImpl : public SmallVectorTemplateBase::value> { + LLVM_VERIFY_ISPODLIKE_CONSISTENCY(T); + using SuperClass = SmallVectorTemplateBase::value>; public: Index: include/llvm/IR/CFG.h =================================================================== --- include/llvm/IR/CFG.h +++ include/llvm/IR/CFG.h @@ -236,10 +236,6 @@ } }; -template struct isPodLike> { - static const bool value = isPodLike::value; -}; - using succ_iterator = SuccIterator; using succ_const_iterator = SuccIterator; using succ_range = iterator_range; Index: include/llvm/Support/type_traits.h =================================================================== --- include/llvm/Support/type_traits.h +++ include/llvm/Support/type_traits.h @@ -33,27 +33,32 @@ // that comes with GCC 5. #if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \ (defined(__GNUC__) && __GNUC__ >= 5) + + // this can be used at instantiation site to ensure the isPodLike + // specialization are compatible with std::is_trivially_copyable, which is a + // requirement for many of the optimizations implied by isPodLike +#define LLVM_VERIFY_ISPODLIKE_CONSISTENCY(T) \ + static_assert(llvm::isPodLike::value == \ + std::is_trivially_copyable::value, \ + "pod-like implies trivially copyable") + // If the compiler supports the is_trivially_copyable trait use it, as it // matches the definition of isPodLike closely. static const bool value = std::is_trivially_copyable::value; #elif __has_feature(is_trivially_copyable) +#define LLVM_VERIFY_ISPODLIKE_CONSISTENCY(T) // Use the internal name if the compiler supports is_trivially_copyable but we // don't know if the standard library does. This is the case for clang in // conjunction with libstdc++ from GCC 4.x. static const bool value = __is_trivially_copyable(T); #else +#define LLVM_VERIFY_ISPODLIKE_CONSISTENCY(T) // If we don't know anything else, we can (at least) assume that all non-class // types are PODs. static const bool value = !std::is_class::value; #endif }; -// std::pair's are pod-like if their elements are. -template -struct isPodLike> { - static const bool value = isPodLike::value && isPodLike::value; -}; - /// Metafunction that determines whether the given type is either an /// integral type or an enumeration type, including enum classes. ///