xref: /llvm-project/clang/test/AST/conditionally-trivial-smfs.cpp (revision 7846d590033e8d661198f4c00f56f46a4993c526)
1 // RUN: %clang_cc1 -std=c++20 -triple x86_64-pc-linux -ast-dump=json %s | FileCheck %s --check-prefixes=CHECK,LIN
2 // RUN: %clang_cc1 -std=c++20 -triple x86_64-pc-win32 -ast-dump=json %s | FileCheck %s
3 
4 // This test validates that we compute correct AST properties of classes with
5 // conditionally trivial special member functions.
6 
7 template <int N>
8 struct DefaultConstructorCheck {
9   DefaultConstructorCheck() requires(N == 1) = default;
10   DefaultConstructorCheck() requires(N == 2) = delete;
11   DefaultConstructorCheck() requires(N == 3);
12   DefaultConstructorCheck();
13 };
14 
15 
16 template struct DefaultConstructorCheck<1>;
17 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
18 // CHECK:             "definitionData": {
19 // CHECK-NEXT:          "canConstDefaultInit": true,
20 // CHECK-NEXT:          "canPassInRegisters": true,
21 // CHECK-NEXT:          "copyAssign": {
22 
23 // CHECK:               "defaultCtor": {
24 // CHECK-NEXT:            "defaultedIsConstexpr": true,
25 // CHECK-NEXT:            "exists": true,
26 // CHECK-NEXT:            "isConstexpr": true,
27 // CHECK-NEXT:            "trivial": true,
28 // CHECK-NEXT:            "userProvided": true
29 // CHECK-NEXT:          },
30 
31 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
32 // CHECK-NEXT:          "hasUserDeclaredConstructor": true,
33 // CHECK-NEXT:          "isEmpty": true,
34 // CHECK-NEXT:          "isLiteral": true,
35 // CHECK-NEXT:          "isStandardLayout": true,
36 // CHECK-NEXT:          "isTrivial": true,
37 // CHECK-NEXT:          "isTriviallyCopyable": true,
38 
39 template struct DefaultConstructorCheck<2>;
40 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
41 // CHECK:             "definitionData": {
42 // CHECK-NEXT:          "canConstDefaultInit": true,
43 // CHECK-NEXT:          "canPassInRegisters": true,
44 // CHECK-NEXT:          "copyAssign": {
45 
46 // CHECK:               "defaultCtor": {
47 // CHECK-NEXT:            "defaultedIsConstexpr": true,
48 // CHECK-NEXT:            "exists": true,
49 // CHECK-NEXT:            "isConstexpr": true,
50 // CHECK-NEXT:            "trivial": true,
51 // CHECK-NEXT:            "userProvided": true
52 // CHECK-NEXT:          },
53 
54 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
55 // CHECK-NEXT:          "hasUserDeclaredConstructor": true,
56 // CHECK-NEXT:          "isEmpty": true,
57 // CHECK-NEXT:          "isLiteral": true,
58 // CHECK-NEXT:          "isStandardLayout": true,
59 // CHECK-NEXT:          "isTrivial": true,
60 // CHECK-NEXT:          "isTriviallyCopyable": true,
61 
62 
63 template struct DefaultConstructorCheck<3>;
64 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
65 // CHECK:             "definitionData": {
66 // CHECK-NEXT:          "canConstDefaultInit": true,
67 // CHECK-NEXT:          "canPassInRegisters": true,
68 // CHECK-NEXT:          "copyAssign": {
69 
70 // CHECK:               "defaultCtor": {
71 // CHECK-NEXT:            "defaultedIsConstexpr": true,
72 // CHECK-NEXT:            "exists": true,
73 // CHECK-NEXT:            "isConstexpr": true,
74 // CHECK-NEXT:            "nonTrivial": true,
75 // CHECK-NEXT:            "userProvided": true
76 // CHECK-NEXT:          },
77 
78 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
79 // CHECK-NEXT:          "hasUserDeclaredConstructor": true,
80 // CHECK-NEXT:          "isEmpty": true,
81 // CHECK-NEXT:          "isLiteral": true,
82 // CHECK-NEXT:          "isStandardLayout": true,
83 // CHECK-NEXT:          "isTriviallyCopyable": true,
84 
85 template <int N>
86 struct CopyConstructorCheck {
87   CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 1) = default;
88   CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 2) = delete;
89   CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 3);
90   CopyConstructorCheck(const CopyConstructorCheck&);
91 };
92 
93 
94 template struct CopyConstructorCheck<1>;
95 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
96 // CHECK:             "definitionData": {
97 // CHECK-NEXT:          "canConstDefaultInit": true,
98 // CHECK-NEXT:          "canPassInRegisters": true,
99 // CHECK-NEXT:          "copyAssign": {
100 
101 // CHECK:               "copyCtor": {
102 // CHECK-NEXT:            "hasConstParam": true,
103 // CHECK-NEXT:            "implicitHasConstParam": true,
104 // CHECK-NEXT:            "trivial": true,
105 // CHECK-NEXT:            "userDeclared": true
106 // CHECK-NEXT:          },
107 
108 // CHECK:               "hasUserDeclaredConstructor": true,
109 // CHECK-NEXT:          "isEmpty": true,
110 // CHECK-NEXT:          "isStandardLayout": true,
111 // CHECK-NEXT:          "isTriviallyCopyable": true,
112 // CHECK-NEXT:          "moveAssign": {},
113 
114 template struct CopyConstructorCheck<2>;
115 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
116 // CHECK:             "definitionData": {
117 // CHECK-NEXT:          "canConstDefaultInit": true,
118 // CHECK-NEXT:          "copyAssign": {
119 
120 // CHECK:               "copyCtor": {
121 // CHECK-NEXT:            "hasConstParam": true,
122 // CHECK-NEXT:            "implicitHasConstParam": true,
123 // CHECK-NEXT:            "trivial": true,
124 // CHECK-NEXT:            "userDeclared": true
125 // CHECK-NEXT:          },
126 
127 // CHECK:               "hasUserDeclaredConstructor": true,
128 // CHECK-NEXT:          "isEmpty": true,
129 // CHECK-NEXT:          "isStandardLayout": true,
130 // CHECK-NEXT:          "isTriviallyCopyable": true,
131 // CHECK-NEXT:          "moveAssign": {},
132 
133 template struct CopyConstructorCheck<3>;
134 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
135 // CHECK:             "definitionData": {
136 // CHECK-NEXT:          "canConstDefaultInit": true,
137 // CHECK-NEXT:          "copyAssign": {
138 
139 // CHECK:               "copyCtor": {
140 // CHECK-NEXT:            "hasConstParam": true,
141 // CHECK-NEXT:            "implicitHasConstParam": true,
142 // CHECK-NEXT:            "nonTrivial": true,
143 // CHECK-NEXT:            "userDeclared": true
144 // CHECK-NEXT:          },
145 
146 // CHECK:               "hasUserDeclaredConstructor": true,
147 // CHECK-NEXT:          "isEmpty": true,
148 // CHECK-NEXT:          "isStandardLayout": true,
149 // CHECK-NEXT:          "moveAssign": {},
150 
151 template <int N>
152 struct MoveConstructorCheck {
153   MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 1) = default;
154   MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 2) = delete;
155   MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 3);
156   MoveConstructorCheck(MoveConstructorCheck&&);
157 };
158 
159 
160 template struct MoveConstructorCheck<1>;
161 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
162 // CHECK:             "definitionData": {
163 // CHECK-NEXT:          "canConstDefaultInit": true,
164 // LIN-NEXT:            "canPassInRegisters": true,
165 // CHECK-NEXT:          "copyAssign": {
166 
167 // CHECK:               "hasUserDeclaredConstructor": true,
168 // CHECK-NEXT:          "isEmpty": true,
169 // CHECK-NEXT:          "isStandardLayout": true,
170 // CHECK-NEXT:          "isTriviallyCopyable": true,
171 // CHECK-NEXT:          "moveAssign": {},
172 // CHECK-NEXT:          "moveCtor": {
173 // CHECK-NEXT:            "exists": true,
174 // CHECK-NEXT:            "trivial": true,
175 // CHECK-NEXT:            "userDeclared": true
176 // CHECK-NEXT:          }
177 
178 template struct MoveConstructorCheck<2>;
179 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
180 // CHECK:             "definitionData": {
181 // CHECK-NEXT:          "canConstDefaultInit": true,
182 // CHECK-NEXT:          "copyAssign": {
183 
184 // CHECK:               "hasUserDeclaredConstructor": true,
185 // CHECK-NEXT:          "isEmpty": true,
186 // CHECK-NEXT:          "isStandardLayout": true,
187 // CHECK-NEXT:          "isTriviallyCopyable": true,
188 // CHECK-NEXT:          "moveAssign": {},
189 // CHECK-NEXT:          "moveCtor": {
190 // CHECK-NEXT:            "exists": true,
191 // CHECK-NEXT:            "trivial": true,
192 // CHECK-NEXT:            "userDeclared": true
193 // CHECK-NEXT:          }
194 
195 template struct MoveConstructorCheck<3>;
196 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
197 // CHECK:             "definitionData": {
198 // CHECK-NEXT:          "canConstDefaultInit": true,
199 // CHECK-NEXT:          "copyAssign": {
200 
201 // CHECK:               "hasUserDeclaredConstructor": true,
202 // CHECK-NEXT:          "isEmpty": true,
203 // CHECK-NEXT:          "isStandardLayout": true,
204 // CHECK-NEXT:          "moveAssign": {},
205 // CHECK-NEXT:          "moveCtor": {
206 // CHECK-NEXT:            "exists": true,
207 // CHECK-NEXT:            "nonTrivial": true,
208 // CHECK-NEXT:            "userDeclared": true
209 // CHECK-NEXT:          }
210 
211 template <int N>
212 struct CopyAssignmentCheck {
213   CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 1) = default;
214   CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 2) = delete;
215   CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 3);
216   CopyAssignmentCheck& operator=(const CopyAssignmentCheck&);
217 };
218 
219 
220 template struct CopyAssignmentCheck<1>;
221 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
222 // CHECK:             "definitionData": {
223 // CHECK-NEXT:          "canConstDefaultInit": true,
224 // CHECK-NEXT:          "canPassInRegisters": true,
225 // CHECK-NEXT           "copyAssign": {
226 // CHECK-NEXT             "hasConstParam": true,
227 // CHECK-NEXT             "implicitHasConstParam": true,
228 // CHECK-NEXT             "trivial": true,
229 // CHECK-NEXT             "userDeclared": true
230 // CHECK-NEXT           },
231 
232 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
233 // CHECK-NEXT           "isAggregate": true,
234 // CHECK-NEXT           "isEmpty": true,
235 // CHECK-NEXT           "isLiteral": true,
236 // CHECK-NEXT           "isStandardLayout": true,
237 // CHECK-NEXT           "isTrivial": true,
238 // CHECK-NEXT           "isTriviallyCopyable": true,
239 // CHECK-NEXT           "moveAssign": {},
240 
241 template struct CopyAssignmentCheck<2>;
242 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
243 // CHECK:             "definitionData": {
244 // CHECK-NEXT:          "canConstDefaultInit": true,
245 // CHECK-NEXT:          "canPassInRegisters": true,
246 // CHECK-NEXT           "copyAssign": {
247 // CHECK-NEXT             "hasConstParam": true,
248 // CHECK-NEXT             "implicitHasConstParam": true,
249 // CHECK-NEXT             "trivial": true,
250 // CHECK-NEXT             "userDeclared": true
251 // CHECK-NEXT           },
252 
253 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
254 // CHECK-NEXT           "isAggregate": true,
255 // CHECK-NEXT           "isEmpty": true,
256 // CHECK-NEXT           "isLiteral": true,
257 // CHECK-NEXT           "isStandardLayout": true,
258 // CHECK-NEXT           "isTrivial": true,
259 // CHECK-NEXT           "isTriviallyCopyable": true,
260 // CHECK-NEXT           "moveAssign": {},
261 
262 template struct CopyAssignmentCheck<3>;
263 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
264 // CHECK:             "definitionData": {
265 // CHECK-NEXT:          "canConstDefaultInit": true,
266 // CHECK-NEXT:          "canPassInRegisters": true,
267 // CHECK-NEXT           "copyAssign": {
268 // CHECK-NEXT             "hasConstParam": true,
269 // CHECK-NEXT             "implicitHasConstParam": true,
270 // CHECK-NEXT             "trivial": true,
271 // CHECK-NEXT             "userDeclared": true
272 // CHECK-NEXT           },
273 
274 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
275 // CHECK-NEXT           "isAggregate": true,
276 // CHECK-NEXT           "isEmpty": true,
277 // CHECK-NEXT           "isLiteral": true,
278 // CHECK-NEXT           "isStandardLayout": true,
279 // CHECK-NEXT           "moveAssign": {},
280 
281 template <int N>
282 struct MoveAssignmentCheck {
283   MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 1) = default;
284   MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 2) = delete;
285   MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 3);
286   MoveAssignmentCheck& operator=(MoveAssignmentCheck&&);
287 };
288 
289 
290 template struct MoveAssignmentCheck<1>;
291 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
292 // CHECK:             "definitionData": {
293 // CHECK-NEXT:          "canConstDefaultInit": true,
294 // CHECK-NEXT:          "copyAssign": {
295 
296 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
297 // CHECK-NEXT:          "isAggregate": true,
298 // CHECK-NEXT:          "isEmpty": true,
299 // CHECK-NEXT:          "isLiteral": true,
300 // CHECK-NEXT:          "isPOD": true,
301 // CHECK-NEXT:          "isStandardLayout": true,
302 // CHECK-NEXT:          "isTrivial": true,
303 // CHECK-NEXT:          "isTriviallyCopyable": true,
304 // CHECK-NEXT:          "moveAssign": {
305 // CHECK-NEXT:            "exists": true,
306 // CHECK-NEXT:            "trivial": true,
307 // CHECK-NEXT:            "userDeclared": true
308 // CHECK-NEXT:          },
309 
310 template struct MoveAssignmentCheck<2>;
311 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
312 // CHECK:             "definitionData": {
313 // CHECK-NEXT:          "canConstDefaultInit": true,
314 // CHECK-NEXT:          "copyAssign": {
315 
316 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
317 // CHECK-NEXT:          "isAggregate": true,
318 // CHECK-NEXT:          "isEmpty": true,
319 // CHECK-NEXT:          "isLiteral": true,
320 // CHECK-NEXT:          "isPOD": true,
321 // CHECK-NEXT:          "isStandardLayout": true,
322 // CHECK-NEXT:          "isTrivial": true,
323 // CHECK-NEXT:          "isTriviallyCopyable": true,
324 // CHECK-NEXT:          "moveAssign": {
325 // CHECK-NEXT:            "exists": true,
326 // CHECK-NEXT:            "trivial": true,
327 // CHECK-NEXT:            "userDeclared": true
328 // CHECK-NEXT:          },
329 
330 template struct MoveAssignmentCheck<3>;
331 // CHECK:             "kind": "ClassTemplateSpecializationDecl",
332 // CHECK:             "definitionData": {
333 // CHECK-NEXT:          "canConstDefaultInit": true,
334 // CHECK-NEXT:          "copyAssign": {
335 
336 // CHECK:               "hasConstexprNonCopyMoveConstructor": true,
337 // CHECK-NEXT:          "isAggregate": true,
338 // CHECK-NEXT:          "isEmpty": true,
339 // CHECK-NEXT:          "isLiteral": true,
340 // CHECK-NEXT:          "isPOD": true,
341 // CHECK-NEXT:          "isStandardLayout": true,
342 // CHECK-NEXT:          "moveAssign": {
343 // CHECK-NEXT:            "exists": true,
344 // CHECK-NEXT:            "nonTrivial": true,
345 // CHECK-NEXT:            "userDeclared": true
346 // CHECK-NEXT:          },
347