1 // RUN: %clang_cc1 -verify -std=c++20 %s
2
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);
9
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.
17
18 // Note that because Clang does not implement DRs 1496 and 1734, we say some
19 // classes are trivial when the SMFs are deleted.
20
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();
27 };
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>));
37
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&);
44 };
45
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>));
55
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&&);
62 };
63
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>));
73
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&&);
80 };
81
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>));
92
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&);
99 };
100
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>));
111
112
113 template <int N>
114 struct KindComparisonChecker1 {
115 KindComparisonChecker1& operator=(const KindComparisonChecker1&) requires C0<N> = default;
116 KindComparisonChecker1& operator=(KindComparisonChecker1&);
117 };
118
119 template <int N>
120 struct KindComparisonChecker2 {
121 KindComparisonChecker2& operator=(const KindComparisonChecker2&) requires C0<N> = default;
122 const KindComparisonChecker2& operator=(KindComparisonChecker2&) const;
123 };
124
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&);
130 };
131
132 static_assert(!__is_trivial(KindComparisonChecker1<0>));
133 static_assert(!__is_trivially_copyable(KindComparisonChecker1<0>));
134
135 static_assert(!__is_trivial(KindComparisonChecker2<0>));
136 static_assert(!__is_trivially_copyable(KindComparisonChecker2<0>));
137
138 static_assert(__is_trivial(KindComparisonChecker3<0>));
139 static_assert(__is_trivially_copyable(KindComparisonChecker3<0>));
140
141 template <class T>
142 concept HasA = requires(T t) {
143 { t.a() };
144 };
145
146 template <class T>
147 concept HasAB = HasA<T> && requires(T t) {
148 { t.b() };
149 };
150
151 template <class T>
152 concept HasAC = HasA<T> && requires(T t) {
153 { t.c() };
154 };
155
156 template <class T>
157 concept HasABC = HasAB<T> && HasAC<T> && requires(T t) {
158 { t.c() };
159 };
160
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();
168 };
169
170 struct A {
171 void a();
172 };
173
174 struct AB {
175 void a();
176 void b();
177 };
178
179 struct ABC {
180 void a();
181 void b();
182 void c();
183 };
184
185 struct AC {
186 void a();
187 void c();
188 };
189
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>), "");
195
196
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;
203 };
204
205 struct Child : CRTPBase<Child> { int x; };
206 static Child c;
207
208
209 namespace GH57046 {
210 template<unsigned N>
211 struct Foo {
FooGH57046::Foo212 Foo() requires (N==1) {} // expected-note {{declared here}}
213 Foo() requires (N==2) = default;
214 };
215
216 template <unsigned N, unsigned M>
217 struct S {
218 Foo<M> data;
SGH57046::S219 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
func()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;
226 }
227 }
228
229 namespace GH59206 {
230
231 struct A {
232 A() = default; //eligible, second constructor unsatisfied
233 template<class... Args>
AGH59206::A234 A(Args&&... args) requires (sizeof...(Args) > 0) {}
235 };
236
237 struct B {
238 B() = default; //ineligible, second constructor more constrained
239 template<class... Args>
BGH59206::B240 B(Args&&... args) requires (sizeof...(Args) == 0) {}
241 };
242
243 struct C {
244 C() = default; //eligible, but
245 template<class... Args> //also eligible and non-trivial
CGH59206::C246 C(Args&&... args) {}
247 };
248
249 struct D : B {};
250
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), "");
255
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), "");
266
267 }
268
269 namespace GH60697 {
270
271 template <class T>
272 struct X {
273 X() requires false = default;
274 };
275 static_assert(!__is_trivial(X<int>));
276
277 template <class T>
278 struct S {
279 S() requires(__is_trivially_constructible(T)) = default;
280
SGH60697::S281 S() requires(!__is_trivially_constructible(T) &&
282 __is_constructible(T)) {}
283
284 T t;
285 };
286
287 struct D {
DGH60697::D288 D(int i) : i(i) {}
289 int i;
290 };
291 static_assert(!__is_trivially_constructible(D));
292 static_assert(!__is_constructible(D));
293 static_assert(!__is_trivial(D));
294
295 static_assert(!__is_trivially_constructible(S<D>));
296 static_assert(!__is_constructible(S<D>));
297
298 static_assert(__is_trivial(S<int>));
299 static_assert(!__is_trivial(S<D>));
300
301 }
302
303 namespace GH62555 {
304
305 template <bool B>
306 struct ExplicitTemplateArgs {
307 ExplicitTemplateArgs(ExplicitTemplateArgs&&) = default;
ExplicitTemplateArgsGH62555::ExplicitTemplateArgs308 ExplicitTemplateArgs(ExplicitTemplateArgs<false>&&) requires B {};
309 };
310
311 static_assert(__is_trivially_copyable(ExplicitTemplateArgs<false>));
312 static_assert(__is_trivially_copyable(ExplicitTemplateArgs<true>));
313
314 }
315