brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.5 KiB · c78bea4 Raw
236 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins -Wno-defaulted-function-deleted2// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins -Wno-defaulted-function-deleted -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=143 4// expected-no-diagnostics5 6template<typename T, bool B> struct trivially_copyable_check {7  static_assert(B == __has_trivial_copy(T), "");8  static_assert(B == __is_trivially_constructible(T, T), "");9  static_assert(B == __is_trivially_constructible(T, const T &), "");10  static_assert(B == __is_trivially_constructible(T, T &&), "");11  typedef void type;12};13template<typename T> using trivially_copyable =14  typename trivially_copyable_check<T, true>::type;15template<typename T> using not_trivially_copyable =16  typename trivially_copyable_check<T, false>::type;17 18struct Trivial {};19using _ = trivially_copyable<Trivial>;20 21// A copy/move constructor for class X is trivial if it is not user-provided,22struct UserProvided {23  UserProvided(const UserProvided &);24};25using _ = not_trivially_copyable<UserProvided>;26 27// its declared parameter type is the same as if it had been implicitly28// declared,29struct NonConstCopy {30  NonConstCopy(NonConstCopy &) = default;31};32#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 1433// Up until (and including) Clang 14, non-const copy constructors were not trivial because of dr217134using _ = not_trivially_copyable<NonConstCopy>;35#else36// In the latest Clang version, all defaulted constructors are trivial, even if non-const, because37// dr2171 is fixed.38static_assert(__has_trivial_copy(NonConstCopy), "");39static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy &), "");40static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), "");41static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), "");42static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), "");43 44struct DefaultedSpecialMembers {45  DefaultedSpecialMembers(const DefaultedSpecialMembers &) = default;46  DefaultedSpecialMembers(DefaultedSpecialMembers &) = default;47  DefaultedSpecialMembers(DefaultedSpecialMembers &&) = default;48};49using _ = trivially_copyable<DefaultedSpecialMembers>;50#endif51 52// class X has no virtual functions53struct VFn {54  virtual void f();55};56using _ = not_trivially_copyable<VFn>;57 58// and no virtual base classes59struct VBase : virtual Trivial {};60using _ = not_trivially_copyable<VBase>;61 62// and the constructor selected to copy/move each [direct subobject] is trivial63struct TemplateCtor {64  template<typename T> TemplateCtor(T &);65};66using _ = trivially_copyable<TemplateCtor>;67struct TemplateCtorMember {68  TemplateCtor tc;69};70using _ = trivially_copyable<TemplateCtorMember>;71 72// We can select a non-trivial copy ctor even if there is a trivial one.73struct MutableTemplateCtorMember {74  mutable TemplateCtor mtc;75};76static_assert(!__is_trivially_constructible(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");77static_assert(__is_trivially_constructible(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");78struct MutableTemplateCtorMember2 {79  MutableTemplateCtorMember2(const MutableTemplateCtorMember2 &) = default;80  MutableTemplateCtorMember2(MutableTemplateCtorMember2 &&) = default;81  mutable TemplateCtor mtc;82};83static_assert(!__is_trivially_constructible(MutableTemplateCtorMember2, const MutableTemplateCtorMember2 &), "");84static_assert(__is_trivially_constructible(MutableTemplateCtorMember2, MutableTemplateCtorMember2 &&), "");85 86// Both trivial and non-trivial special members.87struct TNT {88  TNT(const TNT &) = default; // trivial89  TNT(TNT &); // non-trivial90 91  TNT(TNT &&) = default; // trivial92  TNT(const TNT &&); // non-trivial93};94 95static_assert(!__has_trivial_copy(TNT), "lie deliberately for gcc compatibility");96static_assert(__is_trivially_constructible(TNT, TNT), "");97static_assert(!__is_trivially_constructible(TNT, TNT &), "");98static_assert(__is_trivially_constructible(TNT, const TNT &), "");99static_assert(!__is_trivially_constructible(TNT, volatile TNT &), "");100static_assert(__is_trivially_constructible(TNT, TNT &&), "");101static_assert(!__is_trivially_constructible(TNT, const TNT &&), "");102static_assert(!__is_trivially_constructible(TNT, volatile TNT &&), "");103 104// This has only trivial special members.105struct DerivedFromTNT : TNT {};106 107static_assert(__has_trivial_copy(DerivedFromTNT), "");108static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT), "");109static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &), "");110static_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &), "");111static_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &), "");112static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &&), "");113static_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &&), "");114static_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &&), "");115 116// This has only trivial special members.117struct TNTMember {118  TNT tnt;119};120 121static_assert(__has_trivial_copy(TNTMember), "");122static_assert(__is_trivially_constructible(TNTMember, TNTMember), "");123static_assert(__is_trivially_constructible(TNTMember, TNTMember &), "");124static_assert(__is_trivially_constructible(TNTMember, const TNTMember &), "");125static_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &), "");126static_assert(__is_trivially_constructible(TNTMember, TNTMember &&), "");127static_assert(__is_trivially_constructible(TNTMember, const TNTMember &&), "");128static_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &&), "");129 130struct NCCTNT : NonConstCopy, TNT {};131 132static_assert(!__has_trivial_copy(NCCTNT), "");133static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT), "");134static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &), "");135static_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &), "");136static_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &), "");137static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &&), "");138static_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &&), "");139static_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &&), "");140 141struct TemplateCtorNoMove {142  TemplateCtorNoMove(const TemplateCtorNoMove &) = default;143  template<typename T> TemplateCtorNoMove(T &&);144};145static_assert(__is_trivially_constructible(TemplateCtorNoMove, const TemplateCtorNoMove &), "");146static_assert(!__is_trivially_constructible(TemplateCtorNoMove, TemplateCtorNoMove &&), "");147 148struct UseTemplateCtorNoMove {149  TemplateCtorNoMove tcnm;150};151static_assert(__is_trivially_constructible(UseTemplateCtorNoMove, const UseTemplateCtorNoMove &), "");152static_assert(!__is_trivially_constructible(UseTemplateCtorNoMove, UseTemplateCtorNoMove &&), "");153 154struct TemplateCtorNoMoveSFINAE {155  TemplateCtorNoMoveSFINAE(const TemplateCtorNoMoveSFINAE &) = default;156  template<typename T, typename U = typename T::error> TemplateCtorNoMoveSFINAE(T &&);157};158static_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE, const TemplateCtorNoMoveSFINAE &), "");159static_assert(__is_trivially_constructible(TemplateCtorNoMoveSFINAE, TemplateCtorNoMoveSFINAE &&), "");160 161struct UseTemplateCtorNoMoveSFINAE {162  TemplateCtorNoMoveSFINAE tcnm;163};164static_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE, const UseTemplateCtorNoMoveSFINAE &), "");165static_assert(__is_trivially_constructible(UseTemplateCtorNoMoveSFINAE, UseTemplateCtorNoMoveSFINAE &&), "");166 167namespace TrivialityDependsOnImplicitDeletion {168  struct PrivateMove {169    PrivateMove(const PrivateMove &) = default;170  private:171    PrivateMove(PrivateMove &&);172    friend class Access;173  };174  static_assert(__is_trivially_constructible(PrivateMove, const PrivateMove &), "");175  static_assert(!__is_trivially_constructible(PrivateMove, PrivateMove &&), "");176 177  struct NoAccess {178    PrivateMove pm;179    // NoAccess's move is deleted, so moves of it use PrivateMove's copy ctor,180    // which is trivial.181  };182  static_assert(__is_trivially_constructible(NoAccess, const NoAccess &), "");183  static_assert(__is_trivially_constructible(NoAccess, NoAccess &&), "");184  struct TopNoAccess : NoAccess {};185  static_assert(__is_trivially_constructible(TopNoAccess, const TopNoAccess &), "");186  static_assert(__is_trivially_constructible(TopNoAccess, TopNoAccess &&), "");187 188  struct Access {189    PrivateMove pm;190    // NoAccess's move would *not* be deleted, so is *not* suppressed,191    // so moves of it use PrivateMove's move ctor, which is not trivial.192  };193  static_assert(__is_trivially_constructible(Access, const Access &), "");194  static_assert(!__is_trivially_constructible(Access, Access &&), "");195  struct TopAccess : Access {};196  static_assert(__is_trivially_constructible(TopAccess, const TopAccess &), "");197  static_assert(!__is_trivially_constructible(TopAccess, TopAccess &&), "");198}199 200namespace TrivialityDependsOnDestructor {201  class HasInaccessibleDestructor { ~HasInaccessibleDestructor() = default; };202  struct HasImplicitlyDeletedDestructor : HasInaccessibleDestructor {};203  struct HasImplicitlyDeletedCopyCtor : HasImplicitlyDeletedDestructor {204    HasImplicitlyDeletedCopyCtor() = default;205    template<typename T> HasImplicitlyDeletedCopyCtor(T &&);206    // Copy ctor is deleted but trivial.207    // Move ctor is suppressed.208    HasImplicitlyDeletedCopyCtor(const HasImplicitlyDeletedCopyCtor&) = default;209    HasImplicitlyDeletedCopyCtor(HasImplicitlyDeletedCopyCtor&&) = default;210  };211  struct Test : HasImplicitlyDeletedCopyCtor {212    Test(const Test&) = default;213    Test(Test&&) = default;214  };215  // Implicit copy ctor calls deleted trivial copy ctor.216  static_assert(__has_trivial_copy(Test), "");217  // This is false because the destructor is deleted.218  static_assert(!__is_trivially_constructible(Test, const Test &), "");219  // Implicit move ctor calls template ctor.220  static_assert(!__is_trivially_constructible(Test, Test &&), "");221 222  struct HasAccessibleDestructor { ~HasAccessibleDestructor() = default; };223  struct HasImplicitlyDefaultedDestructor : HasAccessibleDestructor {};224  struct HasImplicitlyDefaultedCopyCtor : HasImplicitlyDefaultedDestructor {225    template<typename T> HasImplicitlyDefaultedCopyCtor(T &&);226    // Copy ctor is trivial.227    // Move ctor is trivial.228  };229  struct Test2 : HasImplicitlyDefaultedCopyCtor {};230  // Implicit copy ctor calls trivial copy ctor.231  static_assert(__has_trivial_copy(Test2), "");232  static_assert(__is_trivially_constructible(Test2, const Test2 &), "");233  // Implicit move ctor calls trivial move ctor.234  static_assert(__is_trivially_constructible(Test2, Test2 &&), "");235}236