Index: docs/ProgrammersManual.rst =================================================================== --- docs/ProgrammersManual.rst +++ docs/ProgrammersManual.rst @@ -1456,7 +1456,7 @@ #. std::vector is exception-safe, and some implementations have pessimizations that copy elements when SmallVector would move them. -#. SmallVector understands ``isPodLike`` and uses realloc aggressively. +#. SmallVector understands ``is_trivially_copyable`` and uses realloc aggressively. #. Many LLVM APIs take a SmallVectorImpl as an out parameter (see the note below). Index: include/llvm/ADT/ArrayRef.h =================================================================== --- include/llvm/ADT/ArrayRef.h +++ include/llvm/ADT/ArrayRef.h @@ -526,12 +526,6 @@ /// @} - // ArrayRefs can be treated like a POD type. - template struct isPodLike; - template struct isPodLike> { - static const bool value = true; - }; - template hash_code hash_value(ArrayRef S) { return hash_combine_range(S.begin(), S.end()); } Index: include/llvm/ADT/DenseMap.h =================================================================== --- include/llvm/ADT/DenseMap.h +++ include/llvm/ADT/DenseMap.h @@ -146,7 +146,8 @@ } const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - if (isPodLike::value && isPodLike::value) { + if (is_trivially_copyable::value && + is_trivially_copyable::value) { // Use a simpler loop when these are trivial types. for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) P->getFirst() = EmptyKey; @@ -422,7 +423,8 @@ setNumEntries(other.getNumEntries()); setNumTombstones(other.getNumTombstones()); - if (isPodLike::value && isPodLike::value) + if (is_trivially_copyable::value && + is_trivially_copyable::value) memcpy(reinterpret_cast(getBuckets()), other.getBuckets(), getNumBuckets() * sizeof(BucketT)); else Index: include/llvm/ADT/ImmutableList.h =================================================================== --- include/llvm/ADT/ImmutableList.h +++ include/llvm/ADT/ImmutableList.h @@ -242,10 +242,6 @@ } }; -template struct isPodLike; -template -struct isPodLike> { static const bool value = true; }; - } // end namespace llvm #endif // LLVM_ADT_IMMUTABLELIST_H Index: include/llvm/ADT/Optional.h =================================================================== --- include/llvm/ADT/Optional.h +++ include/llvm/ADT/Optional.h @@ -29,7 +29,7 @@ namespace optional_detail { /// Storage for any type. -template ::value> struct OptionalStorage { +template ::value> struct OptionalStorage { AlignedCharArrayUnion storage; bool hasVal = false; @@ -184,11 +184,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/PointerIntPair.h =================================================================== --- include/llvm/ADT/PointerIntPair.h +++ include/llvm/ADT/PointerIntPair.h @@ -15,6 +15,7 @@ #define LLVM_ADT_POINTERINTPAIR_H #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" #include #include #include @@ -124,6 +125,16 @@ } }; +// Let incomplete PointerIntPair types be known as trivially copyable. +template +struct is_trivially_copyable> { + static constexpr bool value = true; +#if !defined(NDEBUG) && (__has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5)) + static_assert(std::is_trivially_copyable>::value, "inconsistent behavior between llvm:: and std:: is_trivially_copyable"); +#endif + +}; + template struct PointerIntPairInfo { static_assert(PtrTraits::NumLowBitsAvailable < @@ -174,12 +185,6 @@ } }; -template struct isPodLike; -template -struct isPodLike> { - static const bool value = true; -}; - // Provide specialization of DenseMapInfo for PointerIntPair. template struct DenseMapInfo> { Index: include/llvm/ADT/SmallVector.h =================================================================== --- include/llvm/ADT/SmallVector.h +++ include/llvm/ADT/SmallVector.h @@ -180,9 +180,9 @@ } }; -/// SmallVectorTemplateBase - This is where we put method +/// SmallVectorTemplateBase - This is where we put method /// implementations that are designed to work with non-POD-like T's. -template ::value> +template ::value> class SmallVectorTemplateBase : public SmallVectorTemplateCommon { protected: SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} @@ -236,8 +236,8 @@ }; // Define this out-of-line to dissuade the C++ compiler from inlining it. -template -void SmallVectorTemplateBase::grow(size_t MinSize) { +template +void SmallVectorTemplateBase::grow(size_t MinSize) { if (MinSize > UINT32_MAX) report_bad_alloc_error("SmallVector capacity overflow during allocation"); @@ -260,9 +260,8 @@ this->Capacity = NewCapacity; } - -/// SmallVectorTemplateBase - This is where we put method -/// implementations that are designed to work with POD-like T's. +/// SmallVectorTemplateBase - This is where we put +/// method implementations that are designed to work with POD-like T's. template class SmallVectorTemplateBase : public SmallVectorTemplateCommon { protected: @@ -331,7 +330,7 @@ protected: // Default ctor - Initialize to empty. explicit SmallVectorImpl(unsigned N) - : SmallVectorTemplateBase::value>(N) {} + : SmallVectorTemplateBase(N) {} public: SmallVectorImpl(const SmallVectorImpl &) = delete; Index: include/llvm/ADT/StringRef.h =================================================================== --- include/llvm/ADT/StringRef.h +++ include/llvm/ADT/StringRef.h @@ -928,10 +928,6 @@ LLVM_NODISCARD hash_code hash_value(StringRef S); - // StringRefs can be treated like a POD type. - template struct isPodLike; - template <> struct isPodLike { static const bool value = true; }; - } // end namespace llvm #endif // LLVM_ADT_STRINGREF_H Index: include/llvm/ADT/bit.h =================================================================== --- include/llvm/ADT/bit.h +++ include/llvm/ADT/bit.h @@ -41,11 +41,11 @@ , typename = typename std::enable_if<__is_trivially_copyable(To)>::type , typename = typename std::enable_if<__is_trivially_copyable(From)>::type #else - // This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike - // llvm/Support/type_traits.h's isPodLike we don't want to provide a - // good-enough answer here: developers in that configuration will hit - // compilation failures on the bots instead of locally. That's acceptable - // because it's very few developers, and only until we move past C++11. +// This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike +// llvm/Support/type_traits.h's is_trivially_copyable we don't want to +// provide a good-enough answer here: developers in that configuration will hit +// compilation failures on the bots instead of locally. That's acceptable +// because it's very few developers, and only until we move past C++11. #endif > inline To bit_cast(const From &from) noexcept { Index: include/llvm/Analysis/BlockFrequencyInfoImpl.h =================================================================== --- include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -160,10 +160,6 @@ } // end namespace bfi_detail -template <> struct isPodLike { - static const bool value = true; -}; - /// Base class for BlockFrequencyInfoImpl /// /// BlockFrequencyInfoImplBase has supporting data structures and some Index: include/llvm/Bitcode/BitCodes.h =================================================================== --- include/llvm/Bitcode/BitCodes.h +++ include/llvm/Bitcode/BitCodes.h @@ -160,8 +160,6 @@ }; -template <> struct isPodLike { static const bool value=true; }; - /// BitCodeAbbrev - This class represents an abbreviation record. An /// abbreviation allows a complex record that has redundancy to be stored in a /// specialized format instead of the fully-general, fully-vbr, format. Index: include/llvm/CodeGen/RegisterPressure.h =================================================================== --- include/llvm/CodeGen/RegisterPressure.h +++ include/llvm/CodeGen/RegisterPressure.h @@ -132,10 +132,6 @@ } }; -template <> struct isPodLike { - static const bool value = true; -}; - /// List of PressureChanges in order of increasing, unique PSetID. /// /// Use a small fixed number, because we can fit more PressureChanges in an Index: include/llvm/CodeGen/ScheduleDAG.h =================================================================== --- include/llvm/CodeGen/ScheduleDAG.h +++ include/llvm/CodeGen/ScheduleDAG.h @@ -239,9 +239,6 @@ void dump(const TargetRegisterInfo *TRI = nullptr) const; }; - template <> - struct isPodLike { static const bool value = true; }; - /// Scheduling unit. This is a node in the scheduling DAG. class SUnit { private: Index: include/llvm/CodeGen/SelectionDAGNodes.h =================================================================== --- include/llvm/CodeGen/SelectionDAGNodes.h +++ include/llvm/CodeGen/SelectionDAGNodes.h @@ -232,7 +232,6 @@ return LHS == RHS; } }; -template <> struct isPodLike { static const bool value = true; }; /// Allow casting operators to work directly on /// SDValues as if they were SDNode*'s. Index: include/llvm/CodeGen/SlotIndexes.h =================================================================== --- include/llvm/CodeGen/SlotIndexes.h +++ include/llvm/CodeGen/SlotIndexes.h @@ -302,8 +302,6 @@ } }; - template <> struct isPodLike { static const bool value = true; }; - inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) { li.print(os); return os; Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -75,9 +75,6 @@ } }; -template <> struct isPodLike { - static const bool value = true; -}; /// Target-Independent Code Generator Pass Configuration Options. /// Index: include/llvm/IR/CFG.h =================================================================== --- include/llvm/IR/CFG.h +++ include/llvm/IR/CFG.h @@ -238,10 +238,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/IR/ValueHandle.h =================================================================== --- include/llvm/IR/ValueHandle.h +++ include/llvm/IR/ValueHandle.h @@ -309,15 +309,6 @@ } }; -template -struct isPodLike> { -#ifdef NDEBUG - static const bool value = true; -#else - static const bool value = false; -#endif -}; - /// Value handle that tracks a Value across RAUW. /// /// TrackingVH is designed for situations where a client needs to hold a handle @@ -549,14 +540,6 @@ } }; -template struct isPodLike> { -#ifdef NDEBUG - static const bool value = true; -#else - static const bool value = false; -#endif -}; - } // end namespace llvm #endif // LLVM_IR_VALUEHANDLE_H Index: include/llvm/MC/MCInst.h =================================================================== --- include/llvm/MC/MCInst.h +++ include/llvm/MC/MCInst.h @@ -154,8 +154,6 @@ bool evaluateAsConstantImm(int64_t &Imm) const; }; -template <> struct isPodLike { static const bool value = true; }; - /// Instances of this class represent a single low-level machine /// instruction. class MCInst { Index: include/llvm/Support/ScaledNumber.h =================================================================== --- include/llvm/Support/ScaledNumber.h +++ include/llvm/Support/ScaledNumber.h @@ -887,10 +887,6 @@ Digits >>= Shift; } -template struct isPodLike; -template struct isPodLike> { - static const bool value = true; -}; } // end namespace llvm Index: include/llvm/Support/type_traits.h =================================================================== --- include/llvm/Support/type_traits.h +++ include/llvm/Support/type_traits.h @@ -25,35 +25,6 @@ namespace llvm { -/// isPodLike - This is a type trait that is used to determine whether a given -/// type can be copied around with memcpy instead of running ctors etc. -template -struct isPodLike { - // std::is_trivially_copyable is available in libc++ with clang, libstdc++ - // that comes with GCC 5. MSVC 2015 and newer also have - // std::is_trivially_copyable. -#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \ - (defined(__GNUC__) && __GNUC__ >= 5) || defined(_MSC_VER) - // 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) - // 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 - // 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. @@ -120,6 +91,11 @@ move_construction_triviality_helper(move_construction_triviality_helper&&) = default; ~move_construction_triviality_helper() = default; }; + +template +union trivial_helper { + T t; +}; } // end namespace detail /// An implementation of `std::is_trivially_copy_constructible` since we have @@ -144,6 +120,67 @@ template struct is_trivially_move_constructible : std::true_type {}; +// An implementation of `std::is_trivially_copyable` since STL version +// is not equally supported by all compilers, especially GCC 4.9. +// Uniform implementation of this trait is important for ABI compatibility +// as it has an impact on SmallVector's ABI (among others). +template +class is_trivially_copyable { + + // copy constructors + static constexpr bool has_trivial_copy_constructor = + std::is_copy_constructible>::value; + static constexpr bool has_deleted_copy_constructor = + !std::is_copy_constructible::value; + + // move constructors + static constexpr bool has_trivial_move_constructor = + std::is_move_constructible>::value; + static constexpr bool has_deleted_move_constructor = + !std::is_move_constructible::value; + + // copy assign + static constexpr bool has_trivial_copy_assign = + std::is_copy_assignable>::value; + static constexpr bool has_deleted_copy_assign = + !std::is_copy_assignable::value; + + // move assign + static constexpr bool has_trivial_move_assign = + std::is_move_assignable>::value; + static constexpr bool has_deleted_move_assign = + !std::is_move_assignable::value; + + // destructor + static constexpr bool has_trivial_destructor = + std::is_destructible>::value; + + public: + + static constexpr bool value = + has_trivial_destructor && + (has_deleted_move_assign || has_trivial_move_assign) && + (has_deleted_move_constructor || has_trivial_move_constructor) && + (has_deleted_copy_assign || has_trivial_copy_assign) && + (has_deleted_copy_constructor || has_trivial_copy_constructor) && + (has_trivial_move_assign || has_trivial_move_constructor || has_trivial_copy_assign || has_trivial_copy_constructor); + +#if !defined(NDEBUG) && (__has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5)) + static_assert(value == std::is_trivially_copyable::value, "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); +#endif +}; + +// Let pointer to incomplete types be unconditionally known as trivially copyable. +template +struct is_trivially_copyable { + static constexpr bool value = true; +#if !defined(NDEBUG) && (__has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5)) + static_assert(value == std::is_trivially_copyable::value, "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); +#endif +}; + + + } // end namespace llvm // If the compiler supports detecting whether a class is final, define Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -222,13 +222,6 @@ } // end anonymous namespace -namespace llvm { - -template struct isPodLike; -template <> struct isPodLike { static const bool value = true; }; - -} // end namespace llvm - /// Representation of the alloca slices. /// /// This class represents the slices of an alloca which are formed by its Index: tools/clang/include/clang/AST/BaseSubobject.h =================================================================== --- tools/clang/include/clang/AST/BaseSubobject.h +++ tools/clang/include/clang/AST/BaseSubobject.h @@ -80,11 +80,6 @@ } }; -// It's OK to treat BaseSubobject as a POD type. -template <> struct isPodLike { - static const bool value = true; -}; - } // namespace llvm #endif // LLVM_CLANG_AST_BASESUBOBJECT_H Index: tools/clang/include/clang/AST/CharUnits.h =================================================================== --- tools/clang/include/clang/AST/CharUnits.h +++ tools/clang/include/clang/AST/CharUnits.h @@ -238,10 +238,6 @@ } }; -template <> struct isPodLike { - static const bool value = true; -}; - } // end namespace llvm #endif // LLVM_CLANG_AST_CHARUNITS_H Index: tools/clang/include/clang/AST/DeclAccessPair.h =================================================================== --- tools/clang/include/clang/AST/DeclAccessPair.h +++ tools/clang/include/clang/AST/DeclAccessPair.h @@ -61,12 +61,4 @@ }; } -// Take a moment to tell SmallVector that DeclAccessPair is POD. -namespace llvm { -template struct isPodLike; -template<> struct isPodLike { - static const bool value = true; -}; -} - #endif Index: tools/clang/include/clang/AST/DeclarationName.h =================================================================== --- tools/clang/include/clang/AST/DeclarationName.h +++ tools/clang/include/clang/AST/DeclarationName.h @@ -859,9 +859,6 @@ } }; -template <> -struct isPodLike { static const bool value = true; }; - } // namespace llvm #endif // LLVM_CLANG_AST_DECLARATIONNAME_H Index: tools/clang/include/clang/AST/ExprObjC.h =================================================================== --- tools/clang/include/clang/AST/ExprObjC.h +++ tools/clang/include/clang/AST/ExprObjC.h @@ -256,12 +256,6 @@ } // namespace clang -namespace llvm { - -template <> struct isPodLike : std::true_type {}; - -} // namespace llvm - namespace clang { /// Internal struct for storing Key/value pair. Index: tools/clang/include/clang/AST/GlobalDecl.h =================================================================== --- tools/clang/include/clang/AST/GlobalDecl.h +++ tools/clang/include/clang/AST/GlobalDecl.h @@ -140,13 +140,6 @@ } }; - // GlobalDecl isn't *technically* a POD type. However, its copy constructor, - // copy assignment operator, and destructor are all trivial. - template <> - struct isPodLike { - static const bool value = true; - }; - } // namespace llvm #endif // LLVM_CLANG_AST_GLOBALDECL_H Index: tools/clang/include/clang/AST/Type.h =================================================================== --- tools/clang/include/clang/AST/Type.h +++ tools/clang/include/clang/AST/Type.h @@ -95,9 +95,6 @@ enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; }; - template <> - struct isPodLike { static const bool value = true; }; - } // namespace llvm namespace clang { Index: tools/clang/include/clang/Analysis/ProgramPoint.h =================================================================== --- tools/clang/include/clang/Analysis/ProgramPoint.h +++ tools/clang/include/clang/Analysis/ProgramPoint.h @@ -778,9 +778,6 @@ }; -template <> -struct isPodLike { static const bool value = true; }; - } // end namespace llvm #endif Index: tools/clang/include/clang/Basic/IdentifierTable.h =================================================================== --- tools/clang/include/clang/Basic/IdentifierTable.h +++ tools/clang/include/clang/Basic/IdentifierTable.h @@ -951,9 +951,6 @@ } }; -template <> -struct isPodLike { static const bool value = true; }; - template<> struct PointerLikeTypeTraits { static const void *getAsVoidPointer(clang::Selector P) { Index: tools/clang/include/clang/Basic/SourceLocation.h =================================================================== --- tools/clang/include/clang/Basic/SourceLocation.h +++ tools/clang/include/clang/Basic/SourceLocation.h @@ -26,7 +26,6 @@ namespace llvm { template struct DenseMapInfo; -template struct isPodLike; } // namespace llvm @@ -458,11 +457,6 @@ } }; - template <> - struct isPodLike { static const bool value = true; }; - template <> - struct isPodLike { static const bool value = true; }; - // Teach SmallPtrSet how to handle SourceLocation. template<> struct PointerLikeTypeTraits { Index: tools/clang/include/clang/Lex/Token.h =================================================================== --- tools/clang/include/clang/Lex/Token.h +++ tools/clang/include/clang/Lex/Token.h @@ -329,9 +329,4 @@ } // end namespace clang -namespace llvm { - template <> - struct isPodLike { static const bool value = true; }; -} // end namespace llvm - #endif // LLVM_CLANG_LEX_TOKEN_H Index: tools/clang/include/clang/Sema/CodeCompleteConsumer.h =================================================================== --- tools/clang/include/clang/Sema/CodeCompleteConsumer.h +++ tools/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -656,14 +656,6 @@ } // namespace clang -namespace llvm { - -template <> struct isPodLike { - static const bool value = true; -}; - -} // namespace llvm - namespace clang { /// A builder class used to construct new code-completion strings. Index: tools/clang/include/clang/Sema/Ownership.h =================================================================== --- tools/clang/include/clang/Sema/Ownership.h +++ tools/clang/include/clang/Sema/Ownership.h @@ -129,9 +129,6 @@ } }; - template - struct isPodLike> { static const bool value = true; }; - } // namespace llvm namespace clang { Index: tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h =================================================================== --- tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -670,13 +670,4 @@ } // namespace clang -namespace llvm { - -template struct isPodLike; -template <> struct isPodLike { - static const bool value = true; -}; - -} // namespace llvm - #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H Index: tools/clang/lib/AST/VTableBuilder.cpp =================================================================== --- tools/clang/lib/AST/VTableBuilder.cpp +++ tools/clang/lib/AST/VTableBuilder.cpp @@ -847,6 +847,8 @@ : BaseOffset(CharUnits::Zero()), BaseOffsetInLayoutClass(CharUnits::Zero()), VTableIndex(0) { } + + MethodInfo(MethodInfo const&) = default; }; typedef llvm::DenseMap MethodInfoMapTy; Index: tools/clang/lib/Sema/SemaChecking.cpp =================================================================== --- tools/clang/lib/Sema/SemaChecking.cpp +++ tools/clang/lib/Sema/SemaChecking.cpp @@ -11545,12 +11545,12 @@ class Seq { friend class SequenceTree; - unsigned Index = 0; + unsigned Index; explicit Seq(unsigned N) : Index(N) {} public: - Seq() = default; + Seq() : Index(0) {} }; SequenceTree() { Values.push_back(Value(0)); } Index: tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp =================================================================== --- tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ tools/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -131,10 +131,6 @@ return os; } - template struct isPodLike; - template <> struct isPodLike { - static const bool value = true; - }; } // end llvm namespace #ifndef NDEBUG Index: tools/clang/test/Analysis/llvm-conventions.cpp =================================================================== --- tools/clang/test/Analysis/llvm-conventions.cpp +++ tools/clang/test/Analysis/llvm-conventions.cpp @@ -152,8 +152,6 @@ inline bool operator>=(StringRef LHS, StringRef RHS); inline std::string &operator+=(std::string &buffer, StringRef string); hash_code hash_value(StringRef S); -template struct isPodLike; -template <> struct isPodLike { static const bool value = true; }; } // end of namespace llvm Index: tools/clang/tools/libclang/Indexing.cpp =================================================================== --- tools/clang/tools/libclang/Indexing.cpp +++ tools/clang/tools/libclang/Indexing.cpp @@ -94,9 +94,6 @@ } // end anonymous namespace namespace llvm { - template <> struct isPodLike { - static const bool value = true; - }; template <> struct DenseMapInfo { Index: tools/llvm-diff/DifferenceEngine.cpp =================================================================== --- tools/llvm-diff/DifferenceEngine.cpp +++ tools/llvm-diff/DifferenceEngine.cpp @@ -68,7 +68,7 @@ unsigned NewSize = Storage.size() - 1; if (NewSize) { // Move the slot at the end to the beginning. - if (isPodLike::value) + if (is_trivially_copyable::value) Storage[0] = Storage[NewSize]; else std::swap(Storage[0], Storage[NewSize]); Index: unittests/ADT/ArrayRefTest.cpp =================================================================== --- unittests/ADT/ArrayRefTest.cpp +++ unittests/ADT/ArrayRefTest.cpp @@ -249,4 +249,7 @@ EXPECT_TRUE(AR2.equals(AR2Ref)); } +static_assert(is_trivially_copyable>::value, + "trivially copyable"); + } // end anonymous namespace Index: unittests/ADT/ImmutableListTest.cpp =================================================================== --- unittests/ADT/ImmutableListTest.cpp +++ unittests/ADT/ImmutableListTest.cpp @@ -268,4 +268,7 @@ ASSERT_EQ(6, i); } +static_assert(is_trivially_copyable>>::value, + "trivially copyable"); + } // namespace Index: unittests/ADT/PointerIntPairTest.cpp =================================================================== --- unittests/ADT/PointerIntPairTest.cpp +++ unittests/ADT/PointerIntPairTest.cpp @@ -62,6 +62,9 @@ Pair2.setPointerAndInt(&s, E::Case3); EXPECT_EQ(&s, Pair2.getPointer()); EXPECT_EQ(E::Case3, Pair2.getInt()); + + static_assert(is_trivially_copyable>::value, + "trivially copyable"); } TEST(PointerIntPairTest, DefaultInitialize) { @@ -97,6 +100,11 @@ EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1, PointerLikeTypeTraits::NumLowBitsAvailable); + + static_assert( + is_trivially_copyable< + PointerIntPair>::value, + "trivially copyable"); } } // end anonymous namespace Index: unittests/ADT/StringRefTest.cpp =================================================================== --- unittests/ADT/StringRefTest.cpp +++ unittests/ADT/StringRefTest.cpp @@ -1062,4 +1062,6 @@ EXPECT_EQ(StringRef("Bar"), Strings[1]); } +static_assert(is_trivially_copyable::value, "trivially copyable"); + } // end anonymous namespace Index: unittests/Analysis/BlockFrequencyInfoTest.cpp =================================================================== --- unittests/Analysis/BlockFrequencyInfoTest.cpp +++ unittests/Analysis/BlockFrequencyInfoTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/BlockFrequencyInfoImpl.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/AsmParser/Parser.h" @@ -91,5 +92,8 @@ EXPECT_EQ(BFI.getBlockFreq(BB3).getFrequency(), BB3Freq); } +static_assert(is_trivially_copyable::value, + "trivially copyable"); + } // end anonymous namespace } // end namespace llvm Index: unittests/Bitcode/BitstreamReaderTest.cpp =================================================================== --- unittests/Bitcode/BitstreamReaderTest.cpp +++ unittests/Bitcode/BitstreamReaderTest.cpp @@ -148,4 +148,7 @@ } } +static_assert(is_trivially_copyable::value, + "trivially copyable"); + } // end anonymous namespace Index: unittests/CodeGen/CMakeLists.txt =================================================================== --- unittests/CodeGen/CMakeLists.txt +++ unittests/CodeGen/CMakeLists.txt @@ -19,6 +19,7 @@ MachineInstrTest.cpp MachineOperandTest.cpp ScalableVectorMVTsTest.cpp + TypeTraitsTest.cpp ) add_subdirectory(GlobalISel) Index: unittests/CodeGen/MachineInstrTest.cpp =================================================================== --- unittests/CodeGen/MachineInstrTest.cpp +++ unittests/CodeGen/MachineInstrTest.cpp @@ -273,4 +273,6 @@ StringRef(OS.str()).endswith("filename:1:5")); } +static_assert(is_trivially_copyable::value, "trivially copyable"); + } // end namespace Index: unittests/IR/CFGBuilder.cpp =================================================================== --- unittests/IR/CFGBuilder.cpp +++ unittests/IR/CFGBuilder.cpp @@ -9,6 +9,7 @@ #include "CFGBuilder.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/TypeBuilder.h" @@ -267,3 +268,11 @@ EXPECT_TRUE(isa(B.getOrAddBlock("c")->getTerminator())); EXPECT_TRUE(isa(B.getOrAddBlock("d")->getTerminator())); } + +static_assert(is_trivially_copyable::value, + "trivially copyable"); +static_assert(is_trivially_copyable::value, + "trivially copyable"); +static_assert(is_trivially_copyable::value, "trivially copyable"); +static_assert(is_trivially_copyable::value, + "trivially copyable"); Index: unittests/Support/ScaledNumberTest.cpp =================================================================== --- unittests/Support/ScaledNumberTest.cpp +++ unittests/Support/ScaledNumberTest.cpp @@ -563,4 +563,7 @@ EXPECT_EQ(1u, (n * n).toInt()); } +static_assert(is_trivially_copyable>::value, + "trivially copyable"); + } // end namespace