315 lines · cpp
1// RUN: %clang_cc1 -verify -std=c++20 %s2 3template <int N>4concept C0 = (N == 0);5template <int N>6concept C1 = (N == 1);7template <int N>8concept C2 = (N == 2);9 10// Checks are indexed by:11// Definition:12// 1. Explicitly defaulted definition13// 2. Deleted definition14// 3. User provided definition15// We have a less constrained user provided method that should not disable16// the (copyable) triviality of the type.17 18// Note that because Clang does not implement DRs 1496 and 1734, we say some19// classes are trivial when the SMFs are deleted.20 21template <int N>22struct DefaultConstructorChecker {23 DefaultConstructorChecker() requires C0<N> = default;24 DefaultConstructorChecker() requires C1<N> = delete;25 DefaultConstructorChecker() requires C2<N>;26 DefaultConstructorChecker();27};28static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));29static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));30static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));31static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));32static_assert(__is_trivial(DefaultConstructorChecker<0>));33// FIXME: DR149634static_assert(__is_trivial(DefaultConstructorChecker<1>));35static_assert(!__is_trivial(DefaultConstructorChecker<2>));36static_assert(!__is_trivial(DefaultConstructorChecker<3>));37 38template <int N>39struct CopyConstructorChecker {40 CopyConstructorChecker(const CopyConstructorChecker&) requires C0<N> = default;41 CopyConstructorChecker(const CopyConstructorChecker&) requires C1<N> = delete;42 CopyConstructorChecker(const CopyConstructorChecker&) requires C2<N>;43 CopyConstructorChecker(const CopyConstructorChecker&);44};45 46static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));47// FIXME: DR173448static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));49static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));50static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));51static_assert(!__is_trivial(CopyConstructorChecker<0>));52static_assert(!__is_trivial(CopyConstructorChecker<1>));53static_assert(!__is_trivial(CopyConstructorChecker<2>));54static_assert(!__is_trivial(CopyConstructorChecker<3>));55 56template <int N>57struct MoveConstructorChecker {58 MoveConstructorChecker(MoveConstructorChecker&&) requires C0<N> = default;59 MoveConstructorChecker(MoveConstructorChecker&&) requires C1<N> = delete;60 MoveConstructorChecker(MoveConstructorChecker&&) requires C2<N>;61 MoveConstructorChecker(MoveConstructorChecker&&);62};63 64static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));65// FIXME: DR173466static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));67static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));68static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));69static_assert(!__is_trivial(MoveConstructorChecker<0>));70static_assert(!__is_trivial(MoveConstructorChecker<1>));71static_assert(!__is_trivial(MoveConstructorChecker<2>));72static_assert(!__is_trivial(MoveConstructorChecker<3>));73 74template <int N>75struct MoveAssignmentChecker {76 MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0<N> = default;77 MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1<N> = delete;78 MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2<N>;79 MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);80};81 82static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));83// FIXME: DR1734.84static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));85static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));86static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));87static_assert(__is_trivial(MoveAssignmentChecker<0>));88// FIXME: DR1734.89static_assert(__is_trivial(MoveAssignmentChecker<1>));90static_assert(!__is_trivial(MoveAssignmentChecker<2>));91static_assert(!__is_trivial(MoveAssignmentChecker<3>));92 93template <int N>94struct CopyAssignmentChecker {95 CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C0<N> = default;96 CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C1<N> = delete;97 CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C2<N>;98 CopyAssignmentChecker& operator=(const CopyAssignmentChecker&);99};100 101static_assert(__is_trivially_copyable(CopyAssignmentChecker<0>));102// FIXME: DR1734.103static_assert(__is_trivially_copyable(CopyAssignmentChecker<1>));104static_assert(!__is_trivially_copyable(CopyAssignmentChecker<2>));105static_assert(!__is_trivially_copyable(CopyAssignmentChecker<3>));106static_assert(__is_trivial(CopyAssignmentChecker<0>));107// FIXME: DR1734.108static_assert(__is_trivial(CopyAssignmentChecker<1>));109static_assert(!__is_trivial(CopyAssignmentChecker<2>));110static_assert(!__is_trivial(CopyAssignmentChecker<3>));111 112 113template <int N>114struct KindComparisonChecker1 {115 KindComparisonChecker1& operator=(const KindComparisonChecker1&) requires C0<N> = default;116 KindComparisonChecker1& operator=(KindComparisonChecker1&);117};118 119template <int N>120struct KindComparisonChecker2 {121 KindComparisonChecker2& operator=(const KindComparisonChecker2&) requires C0<N> = default;122 const KindComparisonChecker2& operator=(KindComparisonChecker2&) const;123};124 125template <int N>126struct KindComparisonChecker3 {127 using Alias = KindComparisonChecker3;128 Alias& operator=(const Alias&) requires C0<N> = default;129 KindComparisonChecker3& operator=(const KindComparisonChecker3&);130};131 132static_assert(!__is_trivial(KindComparisonChecker1<0>));133static_assert(!__is_trivially_copyable(KindComparisonChecker1<0>));134 135static_assert(!__is_trivial(KindComparisonChecker2<0>));136static_assert(!__is_trivially_copyable(KindComparisonChecker2<0>));137 138static_assert(__is_trivial(KindComparisonChecker3<0>));139static_assert(__is_trivially_copyable(KindComparisonChecker3<0>));140 141template <class T>142concept HasA = requires(T t) {143 { t.a() };144};145 146template <class T>147concept HasAB = HasA<T> && requires(T t) {148 { t.b() };149};150 151template <class T>152concept HasAC = HasA<T> && requires(T t) {153 { t.c() };154};155 156template <class T>157concept HasABC = HasAB<T> && HasAC<T> && requires(T t) {158 { t.c() };159};160 161template <class T>162struct ComplexConstraints {163 ComplexConstraints() requires HasABC<T> = default;164 ComplexConstraints() requires HasAB<T>;165 ComplexConstraints() requires HasAC<T>;166 ComplexConstraints() requires HasA<T> = delete;167 ComplexConstraints();168};169 170struct A {171 void a();172};173 174struct AB {175 void a();176 void b();177};178 179struct ABC {180 void a();181 void b();182 void c();183};184 185struct AC {186 void a();187 void c();188};189 190static_assert(__is_trivial(ComplexConstraints<ABC>), "");191static_assert(!__is_trivial(ComplexConstraints<AB>), "");192static_assert(!__is_trivial(ComplexConstraints<AC>), "");193static_assert(__is_trivial(ComplexConstraints<A>), "");194static_assert(!__is_trivial(ComplexConstraints<int>), "");195 196 197// This is evaluated at the completion of CRTPBase, while `T` is not yet completed.198// This is probably correct behavior.199template <class T>200struct CRTPBase {201 CRTPBase() requires (sizeof(T) > 0);202 CRTPBase() = default;203};204 205struct Child : CRTPBase<Child> { int x; };206static Child c;207 208 209namespace GH57046 {210template<unsigned N>211struct Foo {212 Foo() requires (N==1) {} // expected-note {{declared here}}213 Foo() requires (N==2) = default;214};215 216template <unsigned N, unsigned M>217struct S {218 Foo<M> data;219 S() requires (N==1) {}220 consteval S() requires (N==2) = default; // expected-note {{non-constexpr constructor 'Foo' cannot be used in a constant expression}}221};222 223void func() {224 S<2, 1> s1; // expected-error {{is not a constant expression}} expected-note {{in call to 'S()'}}225 S<2, 2> s2;226}227}228 229namespace GH59206 {230 231struct A {232 A() = default; //eligible, second constructor unsatisfied233 template<class... Args>234 A(Args&&... args) requires (sizeof...(Args) > 0) {}235};236 237struct B {238 B() = default; //ineligible, second constructor more constrained239 template<class... Args>240 B(Args&&... args) requires (sizeof...(Args) == 0) {}241};242 243struct C {244 C() = default; //eligible, but245 template<class... Args> //also eligible and non-trivial246 C(Args&&... args) {}247};248 249struct D : B {};250 251static_assert(__is_trivially_copyable(A), "");252static_assert(__is_trivially_copyable(B), "");253static_assert(__is_trivially_copyable(C), "");254static_assert(__is_trivially_copyable(D), "");255 256// FIXME: Update when https://github.com/llvm/llvm-project/issues/59206 is257// resolved.258static_assert(!__is_trivial(A), "");259static_assert(!__is_trivial(B), "");260static_assert(!__is_trivial(C), "");261static_assert(__is_trivial(D), "");262static_assert(__is_trivially_constructible(A), "");263static_assert(__is_trivially_constructible(B), "");264static_assert(__is_trivially_constructible(C), "");265static_assert(__is_trivially_constructible(D), "");266 267}268 269namespace GH60697 {270 271template <class T>272struct X {273 X() requires false = default;274};275static_assert(!__is_trivial(X<int>));276 277template <class T>278struct S {279 S() requires(__is_trivially_constructible(T)) = default;280 281 S() requires(!__is_trivially_constructible(T) &&282 __is_constructible(T)) {}283 284 T t;285};286 287struct D {288 D(int i) : i(i) {}289 int i;290};291static_assert(!__is_trivially_constructible(D));292static_assert(!__is_constructible(D));293static_assert(!__is_trivial(D));294 295static_assert(!__is_trivially_constructible(S<D>));296static_assert(!__is_constructible(S<D>));297 298static_assert(__is_trivial(S<int>));299static_assert(!__is_trivial(S<D>));300 301}302 303namespace GH62555 {304 305template <bool B>306struct ExplicitTemplateArgs {307 ExplicitTemplateArgs(ExplicitTemplateArgs&&) = default;308 ExplicitTemplateArgs(ExplicitTemplateArgs<false>&&) requires B {};309};310 311static_assert(__is_trivially_copyable(ExplicitTemplateArgs<false>));312static_assert(__is_trivially_copyable(ExplicitTemplateArgs<true>));313 314}315