diff --git a/clang/test/SemaCXX/is-trivially-relocatable.cpp b/clang/test/SemaCXX/is-trivially-relocatable.cpp new file mode 100644 index 00000000000000..439f7a9ad49ae9 --- /dev/null +++ b/clang/test/SemaCXX/is-trivially-relocatable.cpp @@ -0,0 +1,332 @@ +// RUN: %clang_cc1 -std=c++03 -fsyntax-only -verify %s -triple x86_64-windows-msvc +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s -triple x86_64-windows-msvc +// RUN: %clang_cc1 -std=c++03 -fsyntax-only -verify %s -triple x86_64-apple-darwin10 +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s -triple x86_64-apple-darwin10 + +// expected-no-diagnostics + +#if __cplusplus < 201103L +#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__, "") +// cxx98-error@-1 {{variadic macros are a C99 feature}} +#endif + +template +struct Agg { + T t_; +}; + +template +struct Der : T { +}; + +template +struct Mut { + mutable T t_; +}; + +template +struct Non { + Non(); // make it a non-aggregate + T t_; +}; + +struct CompletelyTrivial { +}; +static_assert(__is_trivially_relocatable(CompletelyTrivial)); +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); + +struct NonTrivialDtor { + ~NonTrivialDtor(); +}; +#if defined(_WIN64) && !defined(__MINGW32__) +static_assert(__is_trivially_relocatable(NonTrivialDtor)); // bug #69394 +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); +#else +static_assert(!__is_trivially_relocatable(NonTrivialDtor)); +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); +#endif + +struct NonTrivialCopyCtor { + NonTrivialCopyCtor(const NonTrivialCopyCtor&); +}; +static_assert(!__is_trivially_relocatable(NonTrivialCopyCtor)); +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); + +struct NonTrivialMutableCopyCtor { + NonTrivialMutableCopyCtor(NonTrivialMutableCopyCtor&); +}; +static_assert(!__is_trivially_relocatable(NonTrivialMutableCopyCtor)); +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); + +#if __cplusplus >= 201103L +struct NonTrivialMoveCtor { + NonTrivialMoveCtor(NonTrivialMoveCtor&&); +}; +static_assert(!__is_trivially_relocatable(NonTrivialMoveCtor)); +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); +#endif + +struct NonTrivialCopyAssign { + NonTrivialCopyAssign& operator=(const NonTrivialCopyAssign&); +}; +static_assert(__is_trivially_relocatable(NonTrivialCopyAssign)); +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); + +struct NonTrivialMutableCopyAssign { + NonTrivialMutableCopyAssign& operator=(NonTrivialMutableCopyAssign&); +}; +static_assert(__is_trivially_relocatable(NonTrivialMutableCopyAssign)); +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); + +#if __cplusplus >= 201103L +struct NonTrivialMoveAssign { + NonTrivialMoveAssign& operator=(NonTrivialMoveAssign&&); +}; +static_assert(!__is_trivially_relocatable(NonTrivialMoveAssign)); +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); +#endif + +struct ImplicitlyDeletedAssign { + int& r; +}; +static_assert(__is_trivially_relocatable(ImplicitlyDeletedAssign)); +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); + +#if __cplusplus >= 201103L +struct DeletedCopyAssign { + DeletedCopyAssign(const DeletedCopyAssign&) = default; + DeletedCopyAssign& operator=(const DeletedCopyAssign&) = delete; + ~DeletedCopyAssign() = default; +}; +static_assert(__is_trivially_relocatable(DeletedCopyAssign)); +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); + +struct DeletedMoveAssign { + DeletedMoveAssign(DeletedMoveAssign&&) = default; + DeletedMoveAssign& operator=(DeletedMoveAssign&&) = delete; + ~DeletedMoveAssign() = default; +}; +#if defined(_WIN64) && !defined(__MINGW32__) +static_assert(!__is_trivially_relocatable(DeletedMoveAssign)); // bug #69394 +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); +#else +static_assert(__is_trivially_relocatable(DeletedMoveAssign)); +static_assert(__is_trivially_relocatable(Agg)); +static_assert(__is_trivially_relocatable(Der)); +static_assert(__is_trivially_relocatable(Mut)); +static_assert(__is_trivially_relocatable(Non)); +#endif + +struct DeletedDestructor { + DeletedDestructor(); + ~DeletedDestructor() = delete; +}; +static_assert(__is_trivially_relocatable(DeletedDestructor)); // bug #38398 +static_assert(!__is_trivially_relocatable(Agg)); +static_assert(!__is_trivially_relocatable(Der)); +static_assert(!__is_trivially_relocatable(Mut)); +static_assert(!__is_trivially_relocatable(Non)); +#endif + +#if __cplusplus >= 202002L +template +struct EligibleNonTrivialDefaultCtor { + EligibleNonTrivialDefaultCtor() requires B; + EligibleNonTrivialDefaultCtor() = default; +}; +// Only the Rule of 5 members (not default ctor) affect trivial relocatability. +static_assert(__is_trivially_relocatable(EligibleNonTrivialDefaultCtor)); +static_assert(__is_trivially_relocatable(EligibleNonTrivialDefaultCtor)); + +template +struct IneligibleNonTrivialDefaultCtor { + IneligibleNonTrivialDefaultCtor(); + IneligibleNonTrivialDefaultCtor() requires B = default; +}; +// Only the Rule of 5 members (not default ctor) affect trivial relocatability. +static_assert(__is_trivially_relocatable(IneligibleNonTrivialDefaultCtor)); +static_assert(__is_trivially_relocatable(IneligibleNonTrivialDefaultCtor)); + +template +struct EligibleNonTrivialCopyCtor { + EligibleNonTrivialCopyCtor(const EligibleNonTrivialCopyCtor&) requires B; + EligibleNonTrivialCopyCtor(const EligibleNonTrivialCopyCtor&) = default; +}; +static_assert(!__is_trivially_relocatable(EligibleNonTrivialCopyCtor)); +static_assert(__is_trivially_relocatable(EligibleNonTrivialCopyCtor)); + +template +struct IneligibleNonTrivialCopyCtor { + IneligibleNonTrivialCopyCtor(const IneligibleNonTrivialCopyCtor&); + IneligibleNonTrivialCopyCtor(const IneligibleNonTrivialCopyCtor&) requires B = default; +}; +static_assert(__is_trivially_relocatable(IneligibleNonTrivialCopyCtor)); +static_assert(!__is_trivially_relocatable(IneligibleNonTrivialCopyCtor)); + +template +struct EligibleNonTrivialMoveCtor { + EligibleNonTrivialMoveCtor(EligibleNonTrivialMoveCtor&&) requires B; + EligibleNonTrivialMoveCtor(EligibleNonTrivialMoveCtor&&) = default; +}; +static_assert(!__is_trivially_relocatable(EligibleNonTrivialMoveCtor)); +#if defined(_WIN64) && !defined(__MINGW32__) +static_assert(!__is_trivially_relocatable(EligibleNonTrivialMoveCtor)); // bug #69394 +#else +static_assert(__is_trivially_relocatable(EligibleNonTrivialMoveCtor)); +#endif + +template +struct IneligibleNonTrivialMoveCtor { + IneligibleNonTrivialMoveCtor(IneligibleNonTrivialMoveCtor&&); + IneligibleNonTrivialMoveCtor(IneligibleNonTrivialMoveCtor&&) requires B = default; +}; +#if defined(_WIN64) && !defined(__MINGW32__) +static_assert(!__is_trivially_relocatable(IneligibleNonTrivialMoveCtor)); // bug #69394 +#else +static_assert(__is_trivially_relocatable(IneligibleNonTrivialMoveCtor)); +#endif +static_assert(!__is_trivially_relocatable(IneligibleNonTrivialMoveCtor)); + +template +struct EligibleNonTrivialCopyAssign { + EligibleNonTrivialCopyAssign& operator=(const EligibleNonTrivialCopyAssign&) requires B; + EligibleNonTrivialCopyAssign& operator=(const EligibleNonTrivialCopyAssign&) = default; +}; +static_assert(__is_trivially_relocatable(EligibleNonTrivialCopyAssign)); +static_assert(__is_trivially_relocatable(EligibleNonTrivialCopyAssign)); + +template +struct IneligibleNonTrivialCopyAssign { + IneligibleNonTrivialCopyAssign& operator=(const IneligibleNonTrivialCopyAssign&); + IneligibleNonTrivialCopyAssign& operator=(const IneligibleNonTrivialCopyAssign&) requires B = default; +}; +static_assert(__is_trivially_relocatable(IneligibleNonTrivialCopyAssign)); +static_assert(__is_trivially_relocatable(IneligibleNonTrivialCopyAssign)); + +template +struct EligibleNonTrivialMoveAssign { + EligibleNonTrivialMoveAssign& operator=(EligibleNonTrivialMoveAssign&&) requires B; + EligibleNonTrivialMoveAssign& operator=(EligibleNonTrivialMoveAssign&&) = default; +}; +static_assert(!__is_trivially_relocatable(EligibleNonTrivialMoveAssign)); +static_assert(!__is_trivially_relocatable(EligibleNonTrivialMoveAssign)); + +template +struct IneligibleNonTrivialMoveAssign { + IneligibleNonTrivialMoveAssign& operator=(IneligibleNonTrivialMoveAssign&&); + IneligibleNonTrivialMoveAssign& operator=(IneligibleNonTrivialMoveAssign&&) requires B = default; +}; +static_assert(!__is_trivially_relocatable(IneligibleNonTrivialMoveAssign)); +static_assert(!__is_trivially_relocatable(IneligibleNonTrivialMoveAssign)); + +template +struct EligibleNonTrivialDtor { + ~EligibleNonTrivialDtor() requires B; + ~EligibleNonTrivialDtor() = default; +}; +#if defined(_WIN64) && !defined(__MINGW32__) +static_assert(__is_trivially_relocatable(EligibleNonTrivialDtor)); // bug #69394 +#else +static_assert(!__is_trivially_relocatable(EligibleNonTrivialDtor)); +#endif +static_assert(__is_trivially_relocatable(EligibleNonTrivialDtor)); + +template +struct IneligibleNonTrivialDtor { + ~IneligibleNonTrivialDtor(); + ~IneligibleNonTrivialDtor() requires B = default; +}; +static_assert(__is_trivially_relocatable(IneligibleNonTrivialDtor)); +#if defined(_WIN64) && !defined(__MINGW32__) +static_assert(__is_trivially_relocatable(IneligibleNonTrivialDtor)); // bug #69394 +#else +static_assert(!__is_trivially_relocatable(IneligibleNonTrivialDtor)); +#endif +#endif + +#if __cplusplus >= 201103L +namespace MutableMembers { + // Make sure Clang properly handles these two tricky cases. + // The copy constructor of MutableFieldUsesNonTrivialCopyCtor + // uses a non-trivial constructor of TMovableButNonTCopyable, + // so MutableFieldUsesNonTrivialCopyCtor's copy constructor is + // not trivial. + + struct TMovableButNonTCopyable { + TMovableButNonTCopyable(TMovableButNonTCopyable&); // user-provided + TMovableButNonTCopyable(TMovableButNonTCopyable&&) = default; + TMovableButNonTCopyable& operator=(TMovableButNonTCopyable&&) = default; + ~TMovableButNonTCopyable() = default; + }; + static_assert(!__is_trivially_copyable(TMovableButNonTCopyable), ""); + static_assert(!__is_trivially_relocatable(TMovableButNonTCopyable), ""); + + struct MutableFieldUsesNonTrivialCopyCtor { + mutable TMovableButNonTCopyable m; + }; + static_assert(!__is_trivially_copyable(MutableFieldUsesNonTrivialCopyCtor), ""); + static_assert(!__is_trivially_relocatable(MutableFieldUsesNonTrivialCopyCtor), ""); + + // The copy constructor of MutableFieldIsMoveOnly is implicitly + // deleted, which makes MutableFieldIsMoveOnly trivially copyable + // and therefore also trivially relocatable. + + struct TMovableButNotCopyable { + TMovableButNotCopyable(TMovableButNotCopyable&) = delete; + TMovableButNotCopyable(TMovableButNotCopyable&&) = default; + TMovableButNotCopyable& operator=(TMovableButNotCopyable&&) = default; + ~TMovableButNotCopyable() = default; + }; + static_assert(__is_trivially_copyable(TMovableButNotCopyable)); +#if defined(_WIN64) && !defined(__MINGW32__) + static_assert(!__is_trivially_relocatable(TMovableButNotCopyable)); // bug #69394 +#else + static_assert(__is_trivially_relocatable(TMovableButNotCopyable)); +#endif + struct MutableFieldIsMoveOnly { + mutable TMovableButNotCopyable m; + }; + static_assert(__is_trivially_copyable(MutableFieldIsMoveOnly)); +#if defined(_WIN64) && !defined(__MINGW32__) + static_assert(!__is_trivially_relocatable(MutableFieldIsMoveOnly)); // bug #69394 +#else + static_assert(__is_trivially_relocatable(MutableFieldIsMoveOnly)); +#endif +} +#endif diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index d40605f56f1edd..f67c36868ec923 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -1437,6 +1437,51 @@ void is_trivially_copyable2() static_assert(!__is_trivially_copyable(const volatile void)); } +void is_trivially_relocatable2() +{ + static_assert(__is_trivially_relocatable(char)); + static_assert(__is_trivially_relocatable(int)); + static_assert(__is_trivially_relocatable(long)); + static_assert(__is_trivially_relocatable(short)); + static_assert(__is_trivially_relocatable(signed char)); + static_assert(__is_trivially_relocatable(wchar_t)); + static_assert(__is_trivially_relocatable(bool)); + static_assert(__is_trivially_relocatable(float)); + static_assert(__is_trivially_relocatable(double)); + static_assert(__is_trivially_relocatable(long double)); + static_assert(__is_trivially_relocatable(unsigned char)); + static_assert(__is_trivially_relocatable(unsigned int)); + static_assert(__is_trivially_relocatable(unsigned long long)); + static_assert(__is_trivially_relocatable(unsigned long)); + static_assert(__is_trivially_relocatable(unsigned short)); + static_assert(__is_trivially_relocatable(ClassType)); + static_assert(__is_trivially_relocatable(Derives)); + static_assert(__is_trivially_relocatable(Enum)); + static_assert(__is_trivially_relocatable(IntAr)); + static_assert(__is_trivially_relocatable(Union)); + static_assert(__is_trivially_relocatable(UnionAr)); + static_assert(__is_trivially_relocatable(TrivialStruct)); + static_assert(__is_trivially_relocatable(NonTrivialStruct)); + static_assert(__is_trivially_relocatable(AllDefaulted)); + static_assert(!__is_trivially_relocatable(AllDeleted)); + + static_assert(!__is_trivially_relocatable(void)); + static_assert(!__is_trivially_relocatable(SuperNonTrivialStruct)); + static_assert(!__is_trivially_relocatable(NonTCStruct)); + static_assert(!__is_trivially_relocatable(ExtDefaulted)); + + static_assert(__is_trivially_relocatable(const int)); + static_assert(__is_trivially_relocatable(volatile int)); + + static_assert(__is_trivially_relocatable(ACompleteType)); + static_assert(!__is_trivially_relocatable(AnIncompleteType)); // expected-error {{incomplete type}} + static_assert(!__is_trivially_relocatable(AnIncompleteType[])); // expected-error {{incomplete type}} + static_assert(!__is_trivially_relocatable(AnIncompleteType[1])); // expected-error {{incomplete type}} + static_assert(!__is_trivially_relocatable(void)); + static_assert(!__is_trivially_relocatable(const volatile void)); +} + + struct CStruct { int one; int two; @@ -3578,15 +3623,18 @@ static_assert(__is_trivially_relocatable(volatile int)); enum Enum {}; static_assert(__is_trivially_relocatable(Enum)); static_assert(__is_trivially_relocatable(Enum[])); +static_assert(__is_trivially_relocatable(AggregateTemplate)); union Union {int x;}; static_assert(__is_trivially_relocatable(Union)); static_assert(__is_trivially_relocatable(Union[])); +static_assert(__is_trivially_relocatable(AggregateTemplate)); struct Trivial {}; static_assert(__is_trivially_relocatable(Trivial)); static_assert(__is_trivially_relocatable(const Trivial)); static_assert(__is_trivially_relocatable(volatile Trivial)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); static_assert(__is_trivially_relocatable(Trivial[])); static_assert(__is_trivially_relocatable(const Trivial[])); @@ -3608,6 +3656,25 @@ static_assert(__is_trivially_relocatable(int[][10])); static_assert(__is_trivially_relocatable(const int[][10])); static_assert(__is_trivially_relocatable(volatile int[][10])); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(!__is_trivially_relocatable(int&)); +static_assert(!__is_trivially_relocatable(const int&)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); + +static_assert(!__is_trivially_relocatable(Polymorph)); +static_assert(!__is_trivially_relocatable(InheritPolymorph)); +static_assert(!__is_trivially_relocatable(AggregateTemplate)); + +static_assert(__is_trivially_relocatable(HasPrivateBase)); +static_assert(__is_trivially_relocatable(HasProtectedBase)); +static_assert(!__is_trivially_relocatable(HasVirtBase)); + struct Incomplete; // expected-note {{forward declaration of 'is_trivially_relocatable::Incomplete'}} bool unused = __is_trivially_relocatable(Incomplete); // expected-error {{incomplete type}} @@ -3618,18 +3685,21 @@ static_assert(!__is_trivially_relocatable(NontrivialDtor)); static_assert(!__is_trivially_relocatable(NontrivialDtor[])); static_assert(!__is_trivially_relocatable(const NontrivialDtor)); static_assert(!__is_trivially_relocatable(volatile NontrivialDtor)); +static_assert(!__is_trivially_relocatable(AggregateTemplate)); struct NontrivialCopyCtor { NontrivialCopyCtor(const NontrivialCopyCtor&) {} }; static_assert(!__is_trivially_relocatable(NontrivialCopyCtor)); static_assert(!__is_trivially_relocatable(NontrivialCopyCtor[])); +static_assert(!__is_trivially_relocatable(AggregateTemplate)); struct NontrivialMoveCtor { NontrivialMoveCtor(NontrivialMoveCtor&&) {} }; static_assert(!__is_trivially_relocatable(NontrivialMoveCtor)); static_assert(!__is_trivially_relocatable(NontrivialMoveCtor[])); +static_assert(!__is_trivially_relocatable(AggregateTemplate)); struct [[clang::trivial_abi]] TrivialAbiNontrivialDtor { ~TrivialAbiNontrivialDtor() {} @@ -3638,6 +3708,8 @@ static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor)); static_assert(__is_trivially_relocatable(TrivialAbiNontrivialDtor[])); static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialDtor)); static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialDtor)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(NonAggregateTemplate)); struct [[clang::trivial_abi]] TrivialAbiNontrivialCopyCtor { TrivialAbiNontrivialCopyCtor(const TrivialAbiNontrivialCopyCtor&) {} @@ -3646,6 +3718,8 @@ static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor)); static_assert(__is_trivially_relocatable(TrivialAbiNontrivialCopyCtor[])); static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialCopyCtor)); static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialCopyCtor)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(NonAggregateTemplate)); // A more complete set of tests for the behavior of trivial_abi can be found in // clang/test/SemaCXX/attr-trivial-abi.cpp @@ -3656,6 +3730,34 @@ static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor)); static_assert(__is_trivially_relocatable(TrivialAbiNontrivialMoveCtor[])); static_assert(__is_trivially_relocatable(const TrivialAbiNontrivialMoveCtor)); static_assert(__is_trivially_relocatable(volatile TrivialAbiNontrivialMoveCtor)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); +static_assert(__is_trivially_relocatable(NonAggregateTemplate)); + +struct NontrivialNonConstCopyConstructor { + NontrivialNonConstCopyConstructor(); + NontrivialNonConstCopyConstructor(NontrivialNonConstCopyConstructor&); + NontrivialNonConstCopyConstructor(const NontrivialNonConstCopyConstructor&) = default; + NontrivialNonConstCopyConstructor& operator=(const NontrivialNonConstCopyConstructor&) = default; + ~NontrivialNonConstCopyConstructor() = default; +}; +static_assert(!__is_trivially_relocatable(NontrivialNonConstCopyConstructor)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); // bug + +struct NontrivialCopyAssignment { + NontrivialCopyAssignment(const NontrivialCopyAssignment&) = default; + NontrivialCopyAssignment& operator=(const NontrivialCopyAssignment&); + ~NontrivialCopyAssignment() = default; +}; +static_assert(__is_trivially_relocatable(NontrivialCopyAssignment)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); + +struct NontrivialMoveAssignment { + NontrivialMoveAssignment(NontrivialMoveAssignment&&) = default; + NontrivialMoveAssignment& operator=(NontrivialMoveAssignment&&); + ~NontrivialMoveAssignment() = default; +}; +static_assert(__is_trivially_relocatable(NontrivialMoveAssignment)); +static_assert(__is_trivially_relocatable(AggregateTemplate)); } // namespace is_trivially_relocatable