Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaCXX / constrained-special-member-functions.cpp
blob8ac17e7838ef871cf734befd4a7245beebad29fd
1 // RUN: %clang_cc1 -verify -std=c++20 %s
3 template <int N>
4 concept C0 = (N == 0);
5 template <int N>
6 concept C1 = (N == 1);
7 template <int N>
8 concept C2 = (N == 2);
10 // Checks are indexed by:
11 // Definition:
12 // 1. Explicitly defaulted definition
13 // 2. Deleted definition
14 // 3. User provided definition
15 // We have a less constrained user provided method that should not disable
16 // the (copyable) triviality of the type.
18 // Note that because Clang does not implement DRs 1496 and 1734, we say some
19 // classes are trivial when the SMFs are deleted.
21 template <int N>
22 struct DefaultConstructorChecker {
23 DefaultConstructorChecker() requires C0<N> = default;
24 DefaultConstructorChecker() requires C1<N> = delete;
25 DefaultConstructorChecker() requires C2<N>;
26 DefaultConstructorChecker();
28 static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
29 static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
30 static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
31 static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
32 static_assert(__is_trivial(DefaultConstructorChecker<0>));
33 // FIXME: DR1496
34 static_assert(__is_trivial(DefaultConstructorChecker<1>));
35 static_assert(!__is_trivial(DefaultConstructorChecker<2>));
36 static_assert(!__is_trivial(DefaultConstructorChecker<3>));
38 template <int N>
39 struct 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&);
46 static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
47 // FIXME: DR1734
48 static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
49 static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
50 static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
51 static_assert(!__is_trivial(CopyConstructorChecker<0>));
52 static_assert(!__is_trivial(CopyConstructorChecker<1>));
53 static_assert(!__is_trivial(CopyConstructorChecker<2>));
54 static_assert(!__is_trivial(CopyConstructorChecker<3>));
56 template <int N>
57 struct MoveConstructorChecker {
58 MoveConstructorChecker(MoveConstructorChecker&&) requires C0<N> = default;
59 MoveConstructorChecker(MoveConstructorChecker&&) requires C1<N> = delete;
60 MoveConstructorChecker(MoveConstructorChecker&&) requires C2<N>;
61 MoveConstructorChecker(MoveConstructorChecker&&);
64 static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
65 // FIXME: DR1734
66 static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
67 static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
68 static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
69 static_assert(!__is_trivial(MoveConstructorChecker<0>));
70 static_assert(!__is_trivial(MoveConstructorChecker<1>));
71 static_assert(!__is_trivial(MoveConstructorChecker<2>));
72 static_assert(!__is_trivial(MoveConstructorChecker<3>));
74 template <int N>
75 struct 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&&);
82 static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
83 // FIXME: DR1734.
84 static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
85 static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
86 static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
87 static_assert(__is_trivial(MoveAssignmentChecker<0>));
88 // FIXME: DR1734.
89 static_assert(__is_trivial(MoveAssignmentChecker<1>));
90 static_assert(!__is_trivial(MoveAssignmentChecker<2>));
91 static_assert(!__is_trivial(MoveAssignmentChecker<3>));
93 template <int N>
94 struct 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&);
101 static_assert(__is_trivially_copyable(CopyAssignmentChecker<0>));
102 // FIXME: DR1734.
103 static_assert(__is_trivially_copyable(CopyAssignmentChecker<1>));
104 static_assert(!__is_trivially_copyable(CopyAssignmentChecker<2>));
105 static_assert(!__is_trivially_copyable(CopyAssignmentChecker<3>));
106 static_assert(__is_trivial(CopyAssignmentChecker<0>));
107 // FIXME: DR1734.
108 static_assert(__is_trivial(CopyAssignmentChecker<1>));
109 static_assert(!__is_trivial(CopyAssignmentChecker<2>));
110 static_assert(!__is_trivial(CopyAssignmentChecker<3>));
113 template <int N>
114 struct KindComparisonChecker1 {
115 KindComparisonChecker1& operator=(const KindComparisonChecker1&) requires C0<N> = default;
116 KindComparisonChecker1& operator=(KindComparisonChecker1&);
119 template <int N>
120 struct KindComparisonChecker2 {
121 KindComparisonChecker2& operator=(const KindComparisonChecker2&) requires C0<N> = default;
122 const KindComparisonChecker2& operator=(KindComparisonChecker2&) const;
125 template <int N>
126 struct KindComparisonChecker3 {
127 using Alias = KindComparisonChecker3;
128 Alias& operator=(const Alias&) requires C0<N> = default;
129 KindComparisonChecker3& operator=(const KindComparisonChecker3&);
132 static_assert(!__is_trivial(KindComparisonChecker1<0>));
133 static_assert(!__is_trivially_copyable(KindComparisonChecker1<0>));
135 static_assert(!__is_trivial(KindComparisonChecker2<0>));
136 static_assert(!__is_trivially_copyable(KindComparisonChecker2<0>));
138 static_assert(__is_trivial(KindComparisonChecker3<0>));
139 static_assert(__is_trivially_copyable(KindComparisonChecker3<0>));
141 template <class T>
142 concept HasA = requires(T t) {
143 { t.a() };
146 template <class T>
147 concept HasAB = HasA<T> && requires(T t) {
148 { t.b() };
151 template <class T>
152 concept HasAC = HasA<T> && requires(T t) {
153 { t.c() };
156 template <class T>
157 concept HasABC = HasAB<T> && HasAC<T> && requires(T t) {
158 { t.c() };
161 template <class T>
162 struct 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();
170 struct A {
171 void a();
174 struct AB {
175 void a();
176 void b();
179 struct ABC {
180 void a();
181 void b();
182 void c();
185 struct AC {
186 void a();
187 void c();
190 static_assert(__is_trivial(ComplexConstraints<ABC>), "");
191 static_assert(!__is_trivial(ComplexConstraints<AB>), "");
192 static_assert(!__is_trivial(ComplexConstraints<AC>), "");
193 static_assert(__is_trivial(ComplexConstraints<A>), "");
194 static_assert(!__is_trivial(ComplexConstraints<int>), "");
197 // This is evaluated at the completion of CRTPBase, while `T` is not yet completed.
198 // This is probably correct behavior.
199 template <class T>
200 struct CRTPBase {
201 CRTPBase() requires (sizeof(T) > 0);
202 CRTPBase() = default;
205 struct Child : CRTPBase<Child> { int x; };
206 static Child c;
209 namespace GH57046 {
210 template<unsigned N>
211 struct Foo {
212 Foo() requires (N==1) {} // expected-note {{declared here}}
213 Foo() requires (N==2) = default;
216 template <unsigned N, unsigned M>
217 struct 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}}
223 void func() {
224 S<2, 1> s1; // expected-error {{is not a constant expression}} expected-note {{in call to 'S()'}}
225 S<2, 2> s2;
229 namespace GH59206 {
231 struct A {
232 A() = default; //eligible, second constructor unsatisfied
233 template<class... Args>
234 A(Args&&... args) requires (sizeof...(Args) > 0) {}
237 struct B {
238 B() = default; //ineligible, second constructor more constrained
239 template<class... Args>
240 B(Args&&... args) requires (sizeof...(Args) == 0) {}
243 struct C {
244 C() = default; //eligible, but
245 template<class... Args> //also eligible and non-trivial
246 C(Args&&... args) {}
249 struct D : B {};
251 static_assert(__is_trivially_copyable(A), "");
252 static_assert(__is_trivially_copyable(B), "");
253 static_assert(__is_trivially_copyable(C), "");
254 static_assert(__is_trivially_copyable(D), "");
256 // FIXME: Update when https://github.com/llvm/llvm-project/issues/59206 is
257 // resolved.
258 static_assert(!__is_trivial(A), "");
259 static_assert(!__is_trivial(B), "");
260 static_assert(!__is_trivial(C), "");
261 static_assert(__is_trivial(D), "");
262 static_assert(__is_trivially_constructible(A), "");
263 static_assert(__is_trivially_constructible(B), "");
264 static_assert(__is_trivially_constructible(C), "");
265 static_assert(__is_trivially_constructible(D), "");
269 namespace GH60697 {
271 template <class T>
272 struct X {
273 X() requires false = default;
275 static_assert(!__is_trivial(X<int>));
277 template <class T>
278 struct S {
279 S() requires(__is_trivially_constructible(T)) = default;
281 S() requires(!__is_trivially_constructible(T) &&
282 __is_constructible(T)) {}
284 T t;
287 struct D {
288 D(int i) : i(i) {}
289 int i;
291 static_assert(!__is_trivially_constructible(D));
292 static_assert(!__is_constructible(D));
293 static_assert(!__is_trivial(D));
295 static_assert(!__is_trivially_constructible(S<D>));
296 static_assert(!__is_constructible(S<D>));
298 static_assert(__is_trivial(S<int>));
299 static_assert(!__is_trivial(S<D>));
303 namespace GH62555 {
305 template <bool B>
306 struct ExplicitTemplateArgs {
307 ExplicitTemplateArgs(ExplicitTemplateArgs&&) = default;
308 ExplicitTemplateArgs(ExplicitTemplateArgs<false>&&) requires B {};
311 static_assert(__is_trivially_copyable(ExplicitTemplateArgs<false>));
312 static_assert(__is_trivially_copyable(ExplicitTemplateArgs<true>));