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