// RUN: %clang_cc1 -verify -std=c++20 %s template concept C0 = (N == 0); template concept C1 = (N == 1); template concept C2 = (N == 2); // Checks are indexed by: // Definition: // 1. Explicitly defaulted definition // 2. Deleted definition // 3. User provided definition // We have a less constrained user provided method that should not disable // the (copyable) triviality of the type. // Note that because Clang does not implement DRs 1496 and 1734, we say some // classes are trivial when the SMFs are deleted. template struct DefaultConstructorChecker { DefaultConstructorChecker() requires C0 = default; DefaultConstructorChecker() requires C1 = delete; DefaultConstructorChecker() requires C2; DefaultConstructorChecker(); }; static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>)); static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>)); static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>)); static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>)); static_assert(__is_trivial(DefaultConstructorChecker<0>)); // FIXME: DR1496 static_assert(__is_trivial(DefaultConstructorChecker<1>)); static_assert(!__is_trivial(DefaultConstructorChecker<2>)); static_assert(!__is_trivial(DefaultConstructorChecker<3>)); template struct CopyConstructorChecker { CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default; CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete; CopyConstructorChecker(const CopyConstructorChecker&) requires C2; CopyConstructorChecker(const CopyConstructorChecker&); }; static_assert(__is_trivially_copyable(CopyConstructorChecker<0>)); // FIXME: DR1734 static_assert(__is_trivially_copyable(CopyConstructorChecker<1>)); static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>)); static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>)); static_assert(!__is_trivial(CopyConstructorChecker<0>)); static_assert(!__is_trivial(CopyConstructorChecker<1>)); static_assert(!__is_trivial(CopyConstructorChecker<2>)); static_assert(!__is_trivial(CopyConstructorChecker<3>)); template struct MoveConstructorChecker { MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default; MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete; MoveConstructorChecker(MoveConstructorChecker&&) requires C2; MoveConstructorChecker(MoveConstructorChecker&&); }; static_assert(__is_trivially_copyable(MoveConstructorChecker<0>)); // FIXME: DR1734 static_assert(__is_trivially_copyable(MoveConstructorChecker<1>)); static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>)); static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>)); static_assert(!__is_trivial(MoveConstructorChecker<0>)); static_assert(!__is_trivial(MoveConstructorChecker<1>)); static_assert(!__is_trivial(MoveConstructorChecker<2>)); static_assert(!__is_trivial(MoveConstructorChecker<3>)); template struct MoveAssignmentChecker { MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default; MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete; MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2; MoveAssignmentChecker& operator=(MoveAssignmentChecker&&); }; static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>)); // FIXME: DR1734. static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>)); static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>)); static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>)); static_assert(__is_trivial(MoveAssignmentChecker<0>)); // FIXME: DR1734. static_assert(__is_trivial(MoveAssignmentChecker<1>)); static_assert(!__is_trivial(MoveAssignmentChecker<2>)); static_assert(!__is_trivial(MoveAssignmentChecker<3>)); template struct CopyAssignmentChecker { CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C0 = default; CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C1 = delete; CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C2; CopyAssignmentChecker& operator=(const CopyAssignmentChecker&); }; static_assert(__is_trivially_copyable(CopyAssignmentChecker<0>)); // FIXME: DR1734. static_assert(__is_trivially_copyable(CopyAssignmentChecker<1>)); static_assert(!__is_trivially_copyable(CopyAssignmentChecker<2>)); static_assert(!__is_trivially_copyable(CopyAssignmentChecker<3>)); static_assert(__is_trivial(CopyAssignmentChecker<0>)); // FIXME: DR1734. static_assert(__is_trivial(CopyAssignmentChecker<1>)); static_assert(!__is_trivial(CopyAssignmentChecker<2>)); static_assert(!__is_trivial(CopyAssignmentChecker<3>)); template struct KindComparisonChecker1 { KindComparisonChecker1& operator=(const KindComparisonChecker1&) requires C0 = default; KindComparisonChecker1& operator=(KindComparisonChecker1&); }; template struct KindComparisonChecker2 { KindComparisonChecker2& operator=(const KindComparisonChecker2&) requires C0 = default; const KindComparisonChecker2& operator=(KindComparisonChecker2&) const; }; template struct KindComparisonChecker3 { using Alias = KindComparisonChecker3; Alias& operator=(const Alias&) requires C0 = default; KindComparisonChecker3& operator=(const KindComparisonChecker3&); }; static_assert(!__is_trivial(KindComparisonChecker1<0>)); static_assert(!__is_trivially_copyable(KindComparisonChecker1<0>)); static_assert(!__is_trivial(KindComparisonChecker2<0>)); static_assert(!__is_trivially_copyable(KindComparisonChecker2<0>)); static_assert(__is_trivial(KindComparisonChecker3<0>)); static_assert(__is_trivially_copyable(KindComparisonChecker3<0>)); template concept HasA = requires(T t) { { t.a() }; }; template concept HasAB = HasA && requires(T t) { { t.b() }; }; template concept HasAC = HasA && requires(T t) { { t.c() }; }; template concept HasABC = HasAB && HasAC && requires(T t) { { t.c() }; }; template struct ComplexConstraints { ComplexConstraints() requires HasABC = default; ComplexConstraints() requires HasAB; ComplexConstraints() requires HasAC; ComplexConstraints() requires HasA = delete; ComplexConstraints(); }; struct A { void a(); }; struct AB { void a(); void b(); }; struct ABC { void a(); void b(); void c(); }; struct AC { void a(); void c(); }; static_assert(__is_trivial(ComplexConstraints), ""); static_assert(!__is_trivial(ComplexConstraints), ""); static_assert(!__is_trivial(ComplexConstraints), ""); static_assert(__is_trivial(ComplexConstraints), ""); static_assert(!__is_trivial(ComplexConstraints), ""); // This is evaluated at the completion of CRTPBase, while `T` is not yet completed. // This is probably correct behavior. template struct CRTPBase { CRTPBase() requires (sizeof(T) > 0); CRTPBase() = default; }; struct Child : CRTPBase { int x; }; static Child c; namespace GH57046 { template struct Foo { Foo() requires (N==1) {} // expected-note {{declared here}} Foo() requires (N==2) = default; }; template struct S { Foo data; S() requires (N==1) {} consteval S() requires (N==2) = default; // expected-note {{non-constexpr constructor 'Foo' cannot be used in a constant expression}} }; void func() { S<2, 1> s1; // expected-error {{is not a constant expression}} expected-note {{in call to 'S()'}} S<2, 2> s2; } } namespace GH59206 { struct A { A() = default; //eligible, second constructor unsatisfied template A(Args&&... args) requires (sizeof...(Args) > 0) {} }; struct B { B() = default; //ineligible, second constructor more constrained template B(Args&&... args) requires (sizeof...(Args) == 0) {} }; struct C { C() = default; //eligible, but template //also eligible and non-trivial C(Args&&... args) {} }; struct D : B {}; static_assert(__is_trivially_copyable(A), ""); static_assert(__is_trivially_copyable(B), ""); static_assert(__is_trivially_copyable(C), ""); static_assert(__is_trivially_copyable(D), ""); // FIXME: Update when https://github.com/llvm/llvm-project/issues/59206 is // resolved. static_assert(!__is_trivial(A), ""); static_assert(!__is_trivial(B), ""); static_assert(!__is_trivial(C), ""); static_assert(__is_trivial(D), ""); static_assert(__is_trivially_constructible(A), ""); static_assert(__is_trivially_constructible(B), ""); static_assert(__is_trivially_constructible(C), ""); static_assert(__is_trivially_constructible(D), ""); } namespace GH60697 { template struct X { X() requires false = default; }; static_assert(!__is_trivial(X)); template struct S { S() requires(__is_trivially_constructible(T)) = default; S() requires(!__is_trivially_constructible(T) && __is_constructible(T)) {} T t; }; struct D { D(int i) : i(i) {} int i; }; static_assert(!__is_trivially_constructible(D)); static_assert(!__is_constructible(D)); static_assert(!__is_trivial(D)); static_assert(!__is_trivially_constructible(S)); static_assert(!__is_constructible(S)); static_assert(__is_trivial(S)); static_assert(!__is_trivial(S)); } namespace GH62555 { template struct ExplicitTemplateArgs { ExplicitTemplateArgs(ExplicitTemplateArgs&&) = default; ExplicitTemplateArgs(ExplicitTemplateArgs&&) requires B {}; }; static_assert(__is_trivially_copyable(ExplicitTemplateArgs)); static_assert(__is_trivially_copyable(ExplicitTemplateArgs)); }