brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.9 KiB · c13c686 Raw
255 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins2// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-deprecated-builtins -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=143// RUN: %clang_cc1 -fsyntax-only -std=c++2b -DDEDUCING_THIS -Wno-deprecated-builtins  %s -verify4 5// expected-no-diagnostics6 7#if DEDUCING_THIS8#define EXPLICIT_PARAMETER(...) this __VA_ARGS__,9#else10#define EXPLICIT_PARAMETER(Param)11#endif12 13 14template<typename T, bool B> struct trivially_assignable_check {15  static_assert(B == __has_trivial_assign(T), "");16  static_assert(B == __is_trivially_assignable(T&, T), "");17  static_assert(B == __is_trivially_assignable(T&, const T &), "");18  static_assert(B == __is_trivially_assignable(T&, T &&), "");19  static_assert(B == __is_trivially_assignable(T&&, T), "");20  static_assert(B == __is_trivially_assignable(T&&, const T &), "");21  static_assert(B == __is_trivially_assignable(T&&, T &&), "");22  typedef void type;23};24template<typename T> using trivially_assignable =25  typename trivially_assignable_check<T, true>::type;26template<typename T> using not_trivially_assignable =27  typename trivially_assignable_check<T, false>::type;28 29struct Trivial {};30using _ = trivially_assignable<Trivial>;31 32// A copy/move assignment operator for class X is trivial if it is not user-provided,33struct UserProvided {34  UserProvided &operator=(EXPLICIT_PARAMETER(UserProvided&)35                          const UserProvided &);36};37using _ = not_trivially_assignable<UserProvided>;38 39// its declared parameter type is the same as if it had been implicitly40// declared,41struct NonConstCopy {42  NonConstCopy &operator=(EXPLICIT_PARAMETER(NonConstCopy&) NonConstCopy &) = default;43#if DEDUCING_THIS44  NonConstCopy &operator=(EXPLICIT_PARAMETER(NonConstCopy&&) NonConstCopy &) = default;45#endif46};47#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 1448// Up until (and including) Clang 14, non-const copy assignment operators were not trivial because49// of dr217150using _ = not_trivially_assignable<NonConstCopy>;51#else52// In the latest Clang version, all defaulted assignment operators are trivial, even if non-const,53// because dr2171 is fixed54static_assert(__has_trivial_assign(NonConstCopy), "");55static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");56static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");57static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");58static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");59static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");60static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");61static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");62static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");63 64struct DefaultedSpecialMembers {65  DefaultedSpecialMembers &operator=(EXPLICIT_PARAMETER(DefaultedSpecialMembers&)66                                     const DefaultedSpecialMembers &) = default;67  DefaultedSpecialMembers &operator=(EXPLICIT_PARAMETER(DefaultedSpecialMembers&)68                                     DefaultedSpecialMembers &) = default;69  DefaultedSpecialMembers &operator=(EXPLICIT_PARAMETER(DefaultedSpecialMembers&)70                                     DefaultedSpecialMembers &&) = default;71#if DEDUCING_THIS72  DefaultedSpecialMembers &operator=(EXPLICIT_PARAMETER(DefaultedSpecialMembers&&)73                                     const DefaultedSpecialMembers &) = default;74  DefaultedSpecialMembers &operator=(EXPLICIT_PARAMETER(DefaultedSpecialMembers&&)75                                     DefaultedSpecialMembers &) = default;76  DefaultedSpecialMembers &operator=(EXPLICIT_PARAMETER(DefaultedSpecialMembers&&)77                                     DefaultedSpecialMembers &&) = default;78#endif79};80using _ = trivially_assignable<DefaultedSpecialMembers>;81#endif82 83// class X has no virtual functions84struct VFn {85  virtual void f();86};87using _ = not_trivially_assignable<VFn>;88 89// and no virtual base classes90struct VBase : virtual Trivial {};91using _ = not_trivially_assignable<VBase>;92 93// and the assignment operator selected to copy/move each [direct subobject] is trivial94struct TemplateCtor {95  template<typename T> TemplateCtor operator=(T &);96};97using _ = trivially_assignable<TemplateCtor>;98struct TemplateCtorMember {99  TemplateCtor tc;100};101using _ = trivially_assignable<TemplateCtorMember>;102struct MutableTemplateCtorMember {103  mutable TemplateCtor mtc;104};105static_assert(!__is_trivially_assignable(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");106static_assert(__is_trivially_assignable(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");107 108// Both trivial and non-trivial special members.109struct TNT {110  TNT &operator=(EXPLICIT_PARAMETER(TNT&) const TNT &) = default; // trivial111  TNT &operator=(EXPLICIT_PARAMETER(TNT&) TNT &); // non-trivial112  TNT &operator=(EXPLICIT_PARAMETER(TNT&) TNT &&) = default; // trivial113  TNT &operator=(EXPLICIT_PARAMETER(TNT&) const TNT &&); // non-trivial114#if DEDUCING_THIS115  TNT &operator=(this TNT&&, const TNT &) = default; // trivial116  TNT &operator=(this TNT&&, TNT &); // non-trivial117  TNT &operator=(this TNT&&, TNT &&) = default; // trivial118  TNT &operator=(this TNT&&, const TNT &&); // non-trivial119#endif120};121 122static_assert(!__has_trivial_assign(TNT), "lie deliberately for gcc compatibility");123static_assert(__is_trivially_assignable(TNT, TNT), "");124static_assert(!__is_trivially_assignable(TNT, TNT &), "");125static_assert(__is_trivially_assignable(TNT, const TNT &), "");126static_assert(!__is_trivially_assignable(TNT, volatile TNT &), "");127static_assert(__is_trivially_assignable(TNT, TNT &&), "");128static_assert(!__is_trivially_assignable(TNT, const TNT &&), "");129static_assert(!__is_trivially_assignable(TNT, volatile TNT &&), "");130 131// This has only trivial special members.132struct DerivedFromTNT : TNT {};133 134static_assert(__has_trivial_assign(DerivedFromTNT), "");135static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT), "");136static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &), "");137static_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &), "");138static_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &), "");139static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &&), "");140static_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &&), "");141static_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &&), "");142 143// This has only trivial special members.144struct TNTMember {145  TNT tnt;146};147 148static_assert(__has_trivial_assign(TNTMember), "");149static_assert(__is_trivially_assignable(TNTMember, TNTMember), "");150static_assert(__is_trivially_assignable(TNTMember, TNTMember &), "");151static_assert(__is_trivially_assignable(TNTMember, const TNTMember &), "");152static_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &), "");153static_assert(__is_trivially_assignable(TNTMember, TNTMember &&), "");154static_assert(__is_trivially_assignable(TNTMember, const TNTMember &&), "");155static_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &&), "");156 157struct NCCTNT : NonConstCopy, TNT {};158 159static_assert(!__has_trivial_assign(NCCTNT), "");160static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT), "");161static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &), "");162static_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &), "");163static_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &), "");164static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &&), "");165static_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &&), "");166static_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &&), "");167 168struct MultipleTrivial {169  // All four of these are trivial.170  MultipleTrivial &operator=(const MultipleTrivial &) & = default;171  MultipleTrivial &operator=(const MultipleTrivial &) && = default;172  MultipleTrivial &operator=(MultipleTrivial &&) & = default;173  MultipleTrivial &operator=(MultipleTrivial &&) && = default;174};175 176using _ = trivially_assignable<MultipleTrivial>;177 178struct RefQualifier {179  RefQualifier &operator=(const RefQualifier &) & = default;180  RefQualifier &operator=(const RefQualifier &) &&;181  RefQualifier &operator=(RefQualifier &&) &;182  RefQualifier &operator=(RefQualifier &&) && = default;183};184struct DerivedFromRefQualifier : RefQualifier {185  // Both of these call the trivial copy operation.186  DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) & = default;187  DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) && = default;188  // Both of these call the non-trivial move operation.189  DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) & = default;190  DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) && = default;191};192static_assert(__is_trivially_assignable(DerivedFromRefQualifier&, const DerivedFromRefQualifier&), "");193static_assert(__is_trivially_assignable(DerivedFromRefQualifier&&, const DerivedFromRefQualifier&), "");194static_assert(!__is_trivially_assignable(DerivedFromRefQualifier&, DerivedFromRefQualifier&&), "");195static_assert(!__is_trivially_assignable(DerivedFromRefQualifier&&, DerivedFromRefQualifier&&), "");196 197struct TemplateAssignNoMove {198  TemplateAssignNoMove &operator=(const TemplateAssignNoMove &) = default;199  template<typename T> TemplateAssignNoMove &operator=(T &&);200};201static_assert(__is_trivially_assignable(TemplateAssignNoMove, const TemplateAssignNoMove &), "");202static_assert(!__is_trivially_assignable(TemplateAssignNoMove, TemplateAssignNoMove &&), "");203 204struct UseTemplateAssignNoMove {205  TemplateAssignNoMove tanm;206};207static_assert(__is_trivially_assignable(UseTemplateAssignNoMove, const UseTemplateAssignNoMove &), "");208static_assert(!__is_trivially_assignable(UseTemplateAssignNoMove, UseTemplateAssignNoMove &&), "");209 210struct TemplateAssignNoMoveSFINAE {211  TemplateAssignNoMoveSFINAE &operator=(const TemplateAssignNoMoveSFINAE &) = default;212  template<typename T, typename U = typename T::error> TemplateAssignNoMoveSFINAE &operator=(T &&);213};214static_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, const TemplateAssignNoMoveSFINAE &), "");215static_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, TemplateAssignNoMoveSFINAE &&), "");216 217struct UseTemplateAssignNoMoveSFINAE {218  TemplateAssignNoMoveSFINAE tanm;219};220static_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, const UseTemplateAssignNoMoveSFINAE &), "");221static_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, UseTemplateAssignNoMoveSFINAE &&), "");222 223namespace TrivialityDependsOnImplicitDeletion {224  struct PrivateMove {225    PrivateMove &operator=(const PrivateMove &) = default;226  private:227    PrivateMove &operator=(PrivateMove &&);228    friend class Access;229  };230  static_assert(__is_trivially_assignable(PrivateMove, const PrivateMove &), "");231  static_assert(!__is_trivially_assignable(PrivateMove, PrivateMove &&), "");232 233  struct NoAccess {234    PrivateMove pm;235    // NoAccess's move would be deleted, so is suppressed,236    // so moves of it use PrivateMove's copy ctor, which is trivial.237  };238  static_assert(__is_trivially_assignable(NoAccess, const NoAccess &), "");239  static_assert(__is_trivially_assignable(NoAccess, NoAccess &&), "");240  struct TopNoAccess : NoAccess {};241  static_assert(__is_trivially_assignable(TopNoAccess, const TopNoAccess &), "");242  static_assert(__is_trivially_assignable(TopNoAccess, TopNoAccess &&), "");243 244  struct Access {245    PrivateMove pm;246    // NoAccess's move would *not* be deleted, so is *not* suppressed,247    // so moves of it use PrivateMove's move ctor, which is not trivial.248  };249  static_assert(__is_trivially_assignable(Access, const Access &), "");250  static_assert(!__is_trivially_assignable(Access, Access &&), "");251  struct TopAccess : Access {};252  static_assert(__is_trivially_assignable(TopAccess, const TopAccess &), "");253  static_assert(!__is_trivially_assignable(TopAccess, TopAccess &&), "");254}255