1 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w %s > %t 2>&1 2 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,CXX11-ELIDE %s 3 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w %s > %t 2>&1 4 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17 %s 5 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w -analyzer-config elide-constructors=false %s > %t 2>&1 6 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,CXX11-NOELIDE %s 7 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w -analyzer-config elide-constructors=false %s > %t 2>&1 8 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17 %s 9 10 class C { 11 public: 12 C(); 13 C(C *); 14 C(int, int); 15 16 static C get(); 17 operator bool() const; 18 }; 19 20 typedef __typeof(sizeof(int)) size_t; 21 void *operator new(size_t size, void *placement); 22 23 namespace operator_new { 24 25 // CHECK: void operatorNewWithConstructor() 26 // CHECK: 1: CFGNewAllocator(C *) 27 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 28 // CHECK-NEXT: 3: new C([B1.2]) 29 void operatorNewWithConstructor() { 30 new C(); 31 } 32 33 // CHECK: void operatorNewWithConstructorWithOperatorNewWithContstructor() 34 // CHECK: 1: CFGNewAllocator(C *) 35 // CHECK-NEXT: 2: CFGNewAllocator(C *) 36 // CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], class C) 37 // CHECK-NEXT: 4: new C([B1.3]) 38 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 39 // CHECK-NEXT: 6: new C([B1.5]) 40 void operatorNewWithConstructorWithOperatorNewWithContstructor() { 41 new C(new C()); 42 } 43 44 // CHECK: void operatorPlacementNewWithConstructorWithinPlacementArgument() 45 // CHECK: 1: CFGNewAllocator(C *) 46 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 47 // CHECK-NEXT: 3: new C([B1.2]) 48 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) 49 // CHECK-NEXT: 5: CFGNewAllocator(C *) 50 // CHECK-NEXT: 6: (CXXConstructExpr, [B1.7], class C) 51 // CHECK-NEXT: 7: new ([B1.4]) C([B1.6]) 52 void operatorPlacementNewWithConstructorWithinPlacementArgument() { 53 new (new C()) C(); 54 } 55 56 } // namespace operator_new 57 58 namespace decl_stmt { 59 60 // CHECK: void simpleVariable() 61 // CHECK: 1: (CXXConstructExpr, [B1.2], class C) 62 // CHECK-NEXT: 2: C c; 63 void simpleVariable() { 64 C c; 65 } 66 67 // CHECK: void simpleVariableWithBraces() 68 // CHECK: 1: {} (CXXConstructExpr, [B1.2], class C) 69 // CHECK-NEXT: 2: C c{}; 70 void simpleVariableWithBraces() { 71 C c{}; 72 } 73 74 // CHECK: void simpleVariableWithConstructorArgument() 75 // CHECK: 1: 0 76 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 77 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C) 78 // CHECK-NEXT: 4: C c(0); 79 void simpleVariableWithConstructorArgument() { 80 C c(0); 81 } 82 83 // CHECK: void simpleVariableWithOperatorNewInConstructorArgument() 84 // CHECK: 1: CFGNewAllocator(C *) 85 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 86 // CHECK-NEXT: 3: new C([B1.2]) 87 // CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.5], class C) 88 // CHECK-NEXT: 5: C c(new C()); 89 void simpleVariableWithOperatorNewInConstructorArgument() { 90 C c(new C()); 91 } 92 93 // CHECK: void simpleVariableWithOperatorNewInBraces() 94 // CHECK: 1: CFGNewAllocator(C *) 95 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 96 // CHECK-NEXT: 3: new C([B1.2]) 97 // CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], class C) 98 // CHECK-NEXT: 5: C c{new C()}; 99 void simpleVariableWithOperatorNewInBraces() { 100 C c{new C()}; 101 } 102 103 // CHECK: void simpleVariableInitializedByValue() 104 // CHECK: 1: C::get 105 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 106 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5]) 107 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 108 // CXX11-NEXT: 4: [B1.3] 109 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 110 // CXX11-NEXT: 6: C c = C::get(); 111 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 112 // CXX17-NEXT: 4: C c = C::get(); 113 void simpleVariableInitializedByValue() { 114 C c = C::get(); 115 } 116 117 // FIXME: Find construction contexts for both branches in C++17. 118 // Note that once it gets detected, the test for the get() branch would not 119 // fail, because FileCheck allows partial matches. 120 // CHECK: void simpleVariableWithTernaryOperator(bool coin) 121 // CHECK: [B1] 122 // CXX11-NEXT: 1: [B4.2] ? [B2.5] : [B3.6] 123 // CXX11-NEXT: 2: [B1.1] 124 // CXX11-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C) 125 // CXX11-NEXT: 4: C c = coin ? C::get() : C(0); 126 // CXX17-NEXT: 1: [B4.2] ? [B2.3] : [B3.4] 127 // CXX17-NEXT: 2: C c = coin ? C::get() : C(0); 128 // CHECK: [B2] 129 // CHECK-NEXT: 1: C::get 130 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 131 // CXX11-ELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B2.5]) 132 // CXX11-NOELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4]) 133 // CXX11-NEXT: 4: [B2.3] 134 // CXX11-ELIDE-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], [B1.3], class C) 135 // CXX11-NOELIDE-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], class C) 136 // CXX17-NEXT: 3: [B2.2]() 137 // CHECK: [B3] 138 // CHECK-NEXT: 1: 0 139 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *) 140 // CXX11-ELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], [B3.6], class C) 141 // CXX11-NOELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C) 142 // CXX11-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 143 // CXX11-NEXT: 5: [B3.4] 144 // CXX11-ELIDE-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], [B1.3], class C) 145 // CXX11-NOELIDE-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], class C) 146 // CXX17-NEXT: 3: [B3.2] (CXXConstructExpr, class C) 147 // CXX17-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 148 // CHECK: [B4] 149 // CHECK-NEXT: 1: coin 150 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 151 // CHECK-NEXT: T: [B4.2] ? ... : ... 152 void simpleVariableWithTernaryOperator(bool coin) { 153 C c = coin ? C::get() : C(0); 154 } 155 156 // CHECK: void simpleVariableWithElidableCopy() 157 // CHECK: 1: 0 158 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 159 // CXX11-ELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], [B1.6], class C) 160 // CXX11-NOELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C) 161 // CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C) 162 // CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 163 // CXX11-NEXT: 5: [B1.4] 164 // CXX11-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], class C) 165 // CXX11-NEXT: 7: C c = C(0); 166 // CXX17-NEXT: 5: C c = C(0); 167 void simpleVariableWithElidableCopy() { 168 C c = C(0); 169 } 170 171 // CHECK: void referenceVariableWithConstructor() 172 // CHECK: 1: 0 173 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 174 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], const class C) 175 // CHECK-NEXT: 4: [B1.3] 176 // CHECK-NEXT: 5: const C &c(0); 177 void referenceVariableWithConstructor() { 178 const C &c(0); 179 } 180 181 // CHECK: void referenceVariableWithInitializer() 182 // CHECK: 1: C() (CXXConstructExpr, [B1.3], class C) 183 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C) 184 // CHECK-NEXT: 3: [B1.2] 185 // CHECK-NEXT: 4: const C &c = C(); 186 void referenceVariableWithInitializer() { 187 const C &c = C(); 188 } 189 190 // CHECK: void referenceVariableWithTernaryOperator(bool coin) 191 // CHECK: [B1] 192 // CXX11-NEXT: 1: [B4.2] ? [B2.5] : [B3.6] 193 // CXX17-NEXT: 1: [B4.2] ? [B2.3] : [B3.4] 194 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C) 195 // CHECK-NEXT: 3: [B1.2] 196 // CHECK-NEXT: 4: const C &c = coin ? C::get() : C(0); 197 // CHECK: [B2] 198 // CHECK-NEXT: 1: C::get 199 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 200 // CXX11-ELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B2.5]) 201 // CXX11-NOELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4]) 202 // CXX11-NEXT: 4: [B2.3] 203 // CXX11-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.3], class C) 204 // CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3]) 205 // CHECK: [B3] 206 // CHECK-NEXT: 1: 0 207 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *) 208 // CXX11-ELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], [B3.6], class C) 209 // CXX11-NOELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C) 210 // CXX11-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 211 // CXX11-NEXT: 5: [B3.4] 212 // CXX11-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.3], class C) 213 // CXX17-NEXT: 3: [B3.2] (CXXConstructExpr, [B1.3], class C) 214 // CXX17-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 215 // CHECK: [B4] 216 // CHECK-NEXT: 1: coin 217 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 218 // CHECK-NEXT: T: [B4.2] ? ... : ... 219 void referenceVariableWithTernaryOperator(bool coin) { 220 const C &c = coin ? C::get() : C(0); 221 } 222 223 } // end namespace decl_stmt 224 225 namespace ctor_initializers { 226 227 class D: public C { 228 C c1; 229 230 public: 231 232 // CHECK: D() 233 // CHECK: 1: (CXXConstructExpr, C() (Base initializer), class C) 234 // CHECK-NEXT: 2: C([B1.1]) (Base initializer) 235 // CHECK-NEXT: 3: CFGNewAllocator(C *) 236 // CHECK-NEXT: 4: (CXXConstructExpr, [B1.5], class C) 237 // CHECK-NEXT: 5: new C([B1.4]) 238 // CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, c1([B1.5]) (Member initializer), class C) 239 // CHECK-NEXT: 7: c1([B1.6]) (Member initializer) 240 D(): C(), c1(new C()) {} 241 242 // CHECK: D(int) 243 // CHECK: 1: (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D) 244 // CHECK-NEXT: 2: D([B1.1]) (Delegating initializer) 245 D(int): D() {} 246 247 // FIXME: Why is CXXRecordTypedCall not present in C++17? Note that once it gets 248 // detected the test would not fail, because FileCheck allows partial matches. 249 // CHECK: D(double) 250 // CHECK: 1: C::get 251 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 252 // CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 253 // CHECK-NEXT: 4: [B1.3] 254 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), class C) 255 // CHECK-NEXT: 6: C([B1.5]) (Base initializer) 256 // CHECK-NEXT: 7: CFGNewAllocator(C *) 257 // CHECK-NEXT: 8: C::get 258 // CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 259 // CXX11-ELIDE-NEXT: 10: [B1.9]() (CXXRecordTypedCall, [B1.11], [B1.12]) 260 // CXX11-NOELIDE-NEXT: 10: [B1.9]() (CXXRecordTypedCall, [B1.11]) 261 // CXX11-NEXT: 11: [B1.10] 262 // CXX11-NEXT: 12: [B1.11] (CXXConstructExpr, [B1.13], class C) 263 // CXX11-NEXT: 13: new C([B1.12]) 264 // CXX11-NEXT: 14: [B1.13] (CXXConstructExpr, c1([B1.13]) (Member initializer), class C) 265 // CXX11-NEXT: 15: c1([B1.14]) (Member initializer) 266 // CXX17-NEXT: 10: [B1.9]() 267 // CXX17-NEXT: 11: new C([B1.10]) 268 // CXX17-NEXT: 12: [B1.11] (CXXConstructExpr, c1([B1.11]) (Member initializer), class C) 269 // CXX17-NEXT: 13: c1([B1.12]) (Member initializer) 270 D(double): C(C::get()), c1(new C(C::get())) {} 271 }; 272 273 // Let's see if initializers work well for fields with destructors. 274 class E { 275 public: 276 static E get(); 277 ~E(); 278 }; 279 280 class F { 281 E e; 282 283 public: 284 // FIXME: There should be no temporary destructor in C++17. 285 // CHECK: F() 286 // CHECK: 1: E::get 287 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class ctor_initializers::E (*)( 288 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7]) 289 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6]) 290 // CXX11-NEXT: 4: [B1.3] (BindTemporary) 291 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class ctor_initializers::E) 292 // CXX11-NEXT: 6: [B1.5] 293 // CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, e([B1.6]) (Member initializer), class ctor_initializers 294 // CXX11-NEXT: 8: e([B1.7]) (Member initializer) 295 // CXX11-NEXT: 9: ~ctor_initializers::E() (Temporary object destructor) 296 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, e([B1.4]) (Member initializer), [B1.4]) 297 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 298 // CXX17-NEXT: 5: e([B1.4]) (Member initializer) 299 // CXX17-NEXT: 6: ~ctor_initializers::E() (Temporary object destructor) 300 F(): e(E::get()) {} 301 }; 302 } // end namespace ctor_initializers 303 304 namespace return_stmt_without_dtor { 305 306 // CHECK: C returnVariable() 307 // CHECK: 1: (CXXConstructExpr, [B1.2], class C) 308 // CHECK-NEXT: 2: C c; 309 // CHECK-NEXT: 3: c 310 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, class C) 311 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 312 // CHECK-NEXT: 6: return [B1.5]; 313 C returnVariable() { 314 C c; 315 return c; 316 } 317 318 // CHECK: C returnEmptyBraces() 319 // CHECK: 1: {} (CXXConstructExpr, [B1.2], class C) 320 // CHECK-NEXT: 2: return [B1.1]; 321 C returnEmptyBraces() { 322 return {}; 323 } 324 325 // CHECK: C returnBracesWithOperatorNew() 326 // CHECK: 1: CFGNewAllocator(C *) 327 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 328 // CHECK-NEXT: 3: new C([B1.2]) 329 // CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], class C) 330 // CHECK-NEXT: 5: return [B1.4]; 331 C returnBracesWithOperatorNew() { 332 return {new C()}; 333 } 334 335 // CHECK: C returnBracesWithMultipleItems() 336 // CHECK: 1: 123 337 // CHECK-NEXT: 2: 456 338 // CHECK-NEXT: 3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], class C) 339 // CHECK-NEXT: 4: return [B1.3]; 340 C returnBracesWithMultipleItems() { 341 return {123, 456}; 342 } 343 344 // CHECK: C returnTemporary() 345 // CXX11-ELIDE: 1: C() (CXXConstructExpr, [B1.2], [B1.3], class C) 346 // CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B1.2], class C) 347 // CXX11-NEXT: 2: [B1.1] 348 // CXX11-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C) 349 // CXX11-NEXT: 4: return [B1.3]; 350 // CXX17: 1: C() (CXXConstructExpr, [B1.2], class C) 351 // CXX17-NEXT: 2: return [B1.1]; 352 C returnTemporary() { 353 return C(); 354 } 355 356 // CHECK: C returnTemporaryWithArgument() 357 // CHECK: 1: nullptr 358 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 359 // CXX11-ELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], [B1.6], class C) 360 // CXX11-NOELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C) 361 // CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C) 362 // CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 363 // CXX11-NEXT: 5: [B1.4] 364 // CXX11-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], class C) 365 // CXX11-NEXT: 7: return [B1.6]; 366 // CXX17-NEXT: 5: return [B1.4]; 367 368 C returnTemporaryWithArgument() { 369 return C(nullptr); 370 } 371 372 // CHECK: C returnTemporaryConstructedByFunction() 373 // CHECK: 1: C::get 374 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 375 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5]) 376 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 377 // CXX11-NEXT: 4: [B1.3] 378 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 379 // CXX11-NEXT: 6: return [B1.5]; 380 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 381 // CXX17-NEXT: 4: return [B1.3]; 382 C returnTemporaryConstructedByFunction() { 383 return C::get(); 384 } 385 386 // CHECK: C returnChainOfCopies() 387 // CHECK: 1: C::get 388 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 389 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5]) 390 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 391 // CXX11-NEXT: 4: [B1.3] 392 // CXX11-ELIDE-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], [B1.8], class C) 393 // CXX11-NOELIDE-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class C) 394 // CXX11-NEXT: 6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 395 // CXX11-NEXT: 7: [B1.6] 396 // CXX11-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.9], class C) 397 // CXX11-NEXT: 9: return [B1.8]; 398 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 399 // CXX17-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, NoOp, class C) 400 // CXX17-NEXT: 5: return [B1.4]; 401 C returnChainOfCopies() { 402 return C(C::get()); 403 } 404 405 } // end namespace return_stmt_without_dtor 406 407 namespace return_stmt_with_dtor { 408 409 class D { 410 public: 411 D(); 412 ~D(); 413 }; 414 415 // CHECK: return_stmt_with_dtor::D returnTemporary() 416 // CXX11-ELIDE: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class return_stmt_with_dtor::D) 417 // CXX11-NOELIDE: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], class return_stmt_with_dtor::D) 418 // CXX11-NEXT: 2: [B1.1] (BindTemporary) 419 // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D) 420 // CXX11-NEXT: 4: [B1.3] 421 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D) 422 // CXX11-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor) 423 // CXX11-NEXT: 7: return [B1.5]; 424 // CXX17: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.3], [B1.2], class return_stmt_w 425 // CXX17-NEXT: 2: [B1.1] (BindTemporary) 426 // CXX17-NEXT: 3: return [B1.2]; 427 D returnTemporary() { 428 return D(); 429 } 430 431 // CHECK: void returnByValueIntoVariable() 432 // CHECK: 1: returnTemporary 433 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class return_stmt_with_dtor::D (*)(void)) 434 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7]) 435 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6]) 436 // CXX11-NEXT: 4: [B1.3] (BindTemporary) 437 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D) 438 // CXX11-NEXT: 6: [B1.5] 439 // CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], class return_stmt_with_dtor::D) 440 // CXX11-NEXT: 8: return_stmt_with_dtor::D d = returnTemporary(); 441 // CXX11-NEXT: 9: ~return_stmt_with_dtor::D() (Temporary object destructor) 442 // CXX11-NEXT: 10: [B1.8].~return_stmt_with_dtor::D() (Implicit destructor) 443 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5], [B1.4]) 444 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 445 // CXX17-NEXT: 5: return_stmt_with_dtor::D d = returnTemporary(); 446 void returnByValueIntoVariable() { 447 D d = returnTemporary(); 448 } 449 450 } // end namespace return_stmt_with_dtor 451 452 namespace temporary_object_expr_without_dtors { 453 454 // TODO: Should provide construction context for the constructor, 455 // even if there is no specific trigger statement here. 456 // CHECK: void simpleTemporary() 457 // CHECK: 1: C() (CXXConstructExpr, class C) 458 void simpleTemporary() { 459 C(); 460 } 461 462 // CHECK: void temporaryInCondition() 463 // CHECK: 1: C() (CXXConstructExpr, [B2.2], class C) 464 // CHECK-NEXT: 2: [B2.1] 465 // CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class C) 466 // CHECK-NEXT: 4: [B2.3].operator bool 467 // CHECK-NEXT: 5: [B2.3] 468 // CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) 469 // CHECK-NEXT: T: if [B2.6] 470 void temporaryInCondition() { 471 if (C()); 472 } 473 474 // CHECK: void temporaryInConditionVariable() 475 // CXX11-ELIDE: 1: C() (CXXConstructExpr, [B2.2], [B2.3], class C) 476 // CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B2.2], class C) 477 // CXX11-NEXT: 2: [B2.1] 478 // CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) 479 // CXX11-NEXT: 4: C c = C(); 480 // CXX11-NEXT: 5: c 481 // CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) 482 // CXX11-NEXT: 7: [B2.6].operator bool 483 // CXX11-NEXT: 8: [B2.6] 484 // CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 485 // CXX11-NEXT: T: if [B2.9] 486 // CXX17: 1: C() (CXXConstructExpr, [B2.2], class C) 487 // CXX17-NEXT: 2: C c = C(); 488 // CXX17-NEXT: 3: c 489 // CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) 490 // CXX17-NEXT: 5: [B2.4].operator bool 491 // CXX17-NEXT: 6: [B2.4] 492 // CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 493 // CXX17-NEXT: T: if [B2.7] 494 void temporaryInConditionVariable() { 495 if (C c = C()); 496 } 497 498 499 // CHECK: void temporaryInForLoopConditionVariable() 500 // CHECK: [B2] 501 // CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B2.2], [B2.3], class C) 502 // CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C) 503 // CXX11-NEXT: 2: [B2.1] 504 // CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) 505 // CXX11-NEXT: 4: C c2 = C(); 506 // CXX11-NEXT: 5: c2 507 // CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) 508 // CXX11-NEXT: 7: [B2.6].operator bool 509 // CXX11-NEXT: 8: [B2.6] 510 // CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 511 // CXX11-NEXT: T: for (...; [B2.9]; ) 512 // CXX17-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C) 513 // CXX17-NEXT: 2: C c2 = C(); 514 // CXX17-NEXT: 3: c2 515 // CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) 516 // CXX17-NEXT: 5: [B2.4].operator bool 517 // CXX17-NEXT: 6: [B2.4] 518 // CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 519 // CXX17-NEXT: T: for (...; [B2.7]; ) 520 // CHECK: [B3] 521 // CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B3.2], [B3.3], class C) 522 // CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C) 523 // CXX11-NEXT: 2: [B3.1] 524 // CXX11-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.4], class C) 525 // CXX11-NEXT: 4: C c1 = C(); 526 // CXX17-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C) 527 // CXX17-NEXT: 2: C c1 = C(); 528 void temporaryInForLoopConditionVariable() { 529 for (C c1 = C(); C c2 = C(); ); 530 } 531 532 533 // CHECK: void temporaryInWhileLoopConditionVariable() 534 // CXX11-ELIDE: 1: C() (CXXConstructExpr, [B2.2], [B2.3], class C) 535 // CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B2.2], class C) 536 // CXX11-NEXT: 2: [B2.1] 537 // CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) 538 // CXX11-NEXT: 4: C c = C(); 539 // CXX11-NEXT: 5: c 540 // CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) 541 // CXX11-NEXT: 7: [B2.6].operator bool 542 // CXX11-NEXT: 8: [B2.6] 543 // CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 544 // CXX11-NEXT: T: while [B2.9] 545 // CXX17: 1: C() (CXXConstructExpr, [B2.2], class C) 546 // CXX17-NEXT: 2: C c = C(); 547 // CXX17-NEXT: 3: c 548 // CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) 549 // CXX17-NEXT: 5: [B2.4].operator bool 550 // CXX17-NEXT: 6: [B2.4] 551 // CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 552 // CXX17-NEXT: T: while [B2.7] 553 void temporaryInWhileLoopConditionVariable() { 554 while (C c = C()); 555 } 556 557 } // end namespace temporary_object_expr_without_dtors 558 559 namespace temporary_object_expr_with_dtors { 560 561 class D { 562 public: 563 D(); 564 D(int); 565 ~D(); 566 567 static D get(); 568 569 operator bool() const; 570 }; 571 572 // CHECK: void simpleTemporary() 573 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D) 574 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 575 // CHECK-NEXT: 3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 576 void simpleTemporary() { 577 D(); 578 } 579 580 // CHECK: void temporaryInCondition() 581 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], [B2.3], class temporary_object_expr_with_dtors::D) 582 // CHECK-NEXT: 2: [B2.1] (BindTemporary) 583 // CHECK-NEXT: 3: [B2.2] 584 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 585 // CHECK-NEXT: 5: [B2.4].operator bool 586 // CHECK-NEXT: 6: [B2.4] 587 // CHECK-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 588 // CHECK-NEXT: 8: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 589 // CHECK-NEXT: T: if [B2.7] 590 void temporaryInCondition() { 591 if (D()); 592 } 593 594 // CHECK: void referenceVariableWithConstructor() 595 // CHECK: 1: 0 596 // CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.4], const class temporary_object_expr_with_dtors::D) 597 // CHECK-NEXT: 3: [B1.2] (BindTemporary) 598 // CHECK-NEXT: 4: [B1.3] 599 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0); 600 // CHECK-NEXT: 6: [B1.5].~temporary_object_expr_with_dtors::D() (Implicit destructor) 601 void referenceVariableWithConstructor() { 602 const D &d(0); 603 } 604 605 // CHECK: void referenceVariableWithInitializer() 606 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.4], class temporary_object_expr_with_dtors::D) 607 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 608 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 609 // CHECK-NEXT: 4: [B1.3] 610 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D(); 611 // CHECK-NEXT: 6: [B1.5].~temporary_object_expr_with_dtors::D() (Implicit destructor) 612 void referenceVariableWithInitializer() { 613 const D &d = D(); 614 } 615 616 // CHECK: void referenceVariableWithTernaryOperator(bool coin) 617 // CXX11: [B1] 618 // CXX11-NEXT: 1: [B4.4].~temporary_object_expr_with_dtors::D() (Implicit destructor) 619 // CXX11: [B2] 620 // CXX11-NEXT: 1: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 621 // CXX11: [B3] 622 // CXX11-NEXT: 1: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 623 // CXX11: [B4] 624 // CXX11-NEXT: 1: [B7.2] ? [B5.8] : [B6.8] 625 // CXX11-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 626 // CXX11-NEXT: 3: [B4.2] 627 // CXX11-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0); 628 // CXX11-NEXT: T: (Temp Dtor) [B6.3] 629 // CXX11: [B5] 630 // CXX11-NEXT: 1: D::get 631 // CXX11-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) 632 // CXX11-ELIDE-NEXT: 3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6], [B5.7]) 633 // CXX11-NOELIDE-NEXT: 3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6]) 634 // CXX11-NEXT: 4: [B5.3] (BindTemporary) 635 // CXX11-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 636 // CXX11-NEXT: 6: [B5.5] 637 // CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D) 638 // CXX11-NEXT: 8: [B5.7] (BindTemporary) 639 // CXX11: [B6] 640 // CXX11-NEXT: 1: 0 641 // CXX11-ELIDE-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], [B6.7], class temporary_object_expr_with_dtors::D) 642 // CXX11-NOELIDE-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], class temporary_object_expr_with_dtors::D) 643 // CXX11-NEXT: 3: [B6.2] (BindTemporary) 644 // CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 645 // CXX11-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 646 // CXX11-NEXT: 6: [B6.5] 647 // CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D) 648 // CXX11-NEXT: 8: [B6.7] (BindTemporary) 649 // CXX11: [B7] 650 // CXX11-NEXT: 1: coin 651 // CXX11-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) 652 // CXX11-NEXT: T: [B7.2] ? ... : ... 653 // CXX17: [B1] 654 // CXX17-NEXT: 1: [B4.2] ? [B2.4] : [B3.4] 655 // CXX17-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 656 // CXX17-NEXT: 3: [B1.2] 657 // CXX17-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0); 658 // CXX17-NEXT: 5: [B1.4].~temporary_object_expr_with_dtors::D() (Implicit destructor) 659 // CXX17: [B2] 660 // CXX17-NEXT: 1: D::get 661 // CXX17-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) 662 // CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3]) 663 // CXX17-NEXT: 4: [B2.3] (BindTemporary) 664 // CXX17: [B3] 665 // CXX17-NEXT: 1: 0 666 // CXX17-NEXT: 2: [B3.1] (CXXConstructExpr, [B1.3], class temporary_object_expr_with_dtors::D) 667 // CXX17-NEXT: 3: [B3.2] (BindTemporary) 668 // CXX17-NEXT: 4: temporary_object_expr_with_dtors::D([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 669 // CXX17: [B4] 670 // CXX17-NEXT: 1: coin 671 // CXX17-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 672 // CXX17-NEXT: T: [B4.2] ? ... : ... 673 void referenceVariableWithTernaryOperator(bool coin) { 674 const D &d = coin ? D::get() : D(0); 675 } 676 677 // CHECK: void referenceWithFunctionalCast() 678 // CHECK: 1: 1 679 // CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.5], class temporary_object_expr_with_dtors::D) 680 // CHECK-NEXT: 3: [B1.2] (BindTemporary) 681 // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B1.3]) (CXXFunctionalCastExpr, ConstructorCon 682 // CHECK-NEXT: 5: [B1.4] 683 // CHECK-NEXT: 6: temporary_object_expr_with_dtors::D &&d = temporary_object_expr_with_dtors::D(1); 684 // CHECK-NEXT: 7: [B1.6].~temporary_object_expr_with_dtors::D() (Implicit destructor) 685 void referenceWithFunctionalCast() { 686 D &&d = D(1); 687 } 688 689 // Test the condition constructor, we don't care about branch constructors here. 690 // CHECK: void constructorInTernaryCondition() 691 // CXX11: 1: 1 692 // CXX11-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], [B7.5], class temporary_object_expr_with_dtors::D) 693 // CXX11-NEXT: 3: [B7.2] (BindTemporary) 694 // CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B7.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 695 // CXX11-NEXT: 5: [B7.4] 696 // CXX11-NEXT: 6: [B7.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 697 // CXX11-NEXT: 7: [B7.6].operator bool 698 // CXX11-NEXT: 8: [B7.6] 699 // CXX11-NEXT: 9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 700 // CXX11-NEXT: T: [B7.9] ? ... : ... 701 // CXX17: 1: 1 702 // CXX17-NEXT: 2: [B4.1] (CXXConstructExpr, [B4.3], [B4.5], class temporary_object_expr_with_dtors::D) 703 // CXX17-NEXT: 3: [B4.2] (BindTemporary) 704 // CXX17-NEXT: 4: temporary_object_expr_with_dtors::D([B4.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 705 // CXX17-NEXT: 5: [B4.4] 706 // CXX17-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 707 // CXX17-NEXT: 7: [B4.6].operator bool 708 // CXX17-NEXT: 8: [B4.6] 709 // CXX17-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 710 // CXX17-NEXT: T: [B4.9] ? ... : ... 711 void constructorInTernaryCondition() { 712 const D &d = D(1) ? D(2) : D(3); 713 } 714 715 } // end namespace temporary_object_expr_with_dtors 716 717 namespace implicit_constructor_conversion { 718 719 class A {}; 720 A get(); 721 722 class B { 723 public: 724 B(const A &); 725 ~B() {} 726 }; 727 728 // CHECK: void implicitConstructionConversionFromTemporary() 729 // CHECK: 1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A) 730 // CXX11-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 731 // CXX11-NEXT: 3: [B1.2] 732 // CXX11-ELIDE-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], [B1.9], class implicit_constructor_conversion::B) 733 // CXX11-NOELIDE-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], class implicit_constructor_conversion::B) 734 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 735 // CXX11-NEXT: 6: [B1.5] (BindTemporary) 736 // CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 737 // CXX11-NEXT: 8: [B1.7] 738 // CXX11-NEXT: 9: [B1.8] (CXXConstructExpr, [B1.10], class implicit_constructor_conversion::B) 739 // CXX11-NEXT: 10: implicit_constructor_conversion::B b = implicit_constructor_conversion::A(); 740 // CXX11-NEXT: 11: ~implicit_constructor_conversion::B() (Temporary object destructor) 741 // CXX11-NEXT: 12: [B1.10].~implicit_constructor_conversion::B() (Implicit destructor) 742 // CXX17-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 743 // CXX17-NEXT: 3: [B1.2] 744 // CXX17-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], class implicit_constructor_conversion::B) 745 // CXX17-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 746 // CXX17-NEXT: 6: implicit_constructor_conversion::B b = implicit_constructor_conversion::A(); 747 // CXX17-NEXT: 7: [B1.6].~implicit_constructor_conversion::B() (Implicit destructor) 748 void implicitConstructionConversionFromTemporary() { 749 B b = A(); 750 } 751 752 // CHECK: void implicitConstructionConversionFromFunctionValue() 753 // CHECK: 1: get 754 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conversion::A (*)(void)) 755 // CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 756 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 757 // CHECK-NEXT: 5: [B1.4] 758 // CXX11-ELIDE-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class implicit_constructor_conversion::B) 759 // CXX11-NOELIDE-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], class implicit_constructor_conversion::B) 760 // CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 761 // CXX11-NEXT: 8: [B1.7] (BindTemporary) 762 // CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 763 // CXX11-NEXT: 10: [B1.9] 764 // CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], class implicit_constructor_conversion::B) 765 // CXX11-NEXT: 12: implicit_constructor_conversion::B b = get(); 766 // CXX11-NEXT: 13: ~implicit_constructor_conversion::B() (Temporary object destructor) 767 // CXX11-NEXT: 14: [B1.12].~implicit_constructor_conversion::B() (Implicit destructor) 768 // CXX17-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], class implicit_constructor_conversion::B) 769 // CXX17-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 770 // CXX17-NEXT: 8: implicit_constructor_conversion::B b = get(); 771 // CXX17-NEXT: 9: [B1.8].~implicit_constructor_conversion::B() (Implicit destructor) 772 void implicitConstructionConversionFromFunctionValue() { 773 B b = get(); 774 } 775 776 // CHECK: void implicitConstructionConversionFromTemporaryWithLifetimeExtension() 777 // CHECK: 1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A) 778 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 779 // CHECK-NEXT: 3: [B1.2] 780 // CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.7], class implicit_constructor_conversion::B) 781 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 782 // CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 783 // CHECK-NEXT: 7: [B1.6] 784 // CHECK-NEXT: 8: const implicit_constructor_conversion::B &b = implicit_constructor_conversion::A(); 785 // CHECK-NEXT: 9: [B1.8].~implicit_constructor_conversion::B() (Implicit destructor) 786 void implicitConstructionConversionFromTemporaryWithLifetimeExtension() { 787 const B &b = A(); 788 } 789 790 // CHECK: void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() 791 // CHECK: 1: get 792 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver 793 // CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 794 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 795 // CHECK-NEXT: 5: [B1.4] 796 // CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.9], class implicit_constructor_conversion::B) 797 // CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers 798 // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 799 // CHECK-NEXT: 9: [B1.8] 800 // CHECK-NEXT: 10: const implicit_constructor_conversion::B &b = get(); 801 // CHECK-NEXT: 11: [B1.10].~implicit_constructor_conversion::B() (Implicit destructor) 802 void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() { 803 const B &b = get(); // no-crash 804 } 805 806 } // end namespace implicit_constructor_conversion 807 808 namespace argument_constructors { 809 class D { 810 public: 811 D(); 812 ~D(); 813 }; 814 815 class E { 816 public: 817 E(D d); 818 E(D d1, D d2); 819 }; 820 821 void useC(C c); 822 void useCByReference(const C &c); 823 void useD(D d); 824 void useDByReference(const D &d); 825 void useCAndD(C c, D d); 826 827 // CHECK: void passArgument() 828 // CHECK: 1: useC 829 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C)) 830 // CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], class C) 831 // CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C) 832 // CXX11-NEXT: 4: [B1.3] 833 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6]+0, class C) 834 // CXX11-NEXT: 6: [B1.2]([B1.5]) 835 // CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.4]+0, class C) 836 // CXX17-NEXT: 4: [B1.2]([B1.3]) 837 void passArgument() { 838 useC(C()); 839 } 840 841 // CHECK: void passTwoArguments() 842 // CHECK: [B1] 843 // CHECK-NEXT: 1: useCAndD 844 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C, class argument_constructors::D)) 845 // CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], class C) 846 // CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C) 847 // CXX11-NEXT: 4: [B1.3] 848 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.12]+0, class C) 849 // CXX11-ELIDE-NEXT: 6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], [B1.10], class argument_constructors::D) 850 // CXX11-NOELIDE-NEXT: 6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], class argument_constructors::D) 851 // CXX11-NEXT: 7: [B1.6] (BindTemporary) 852 // CXX11-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 853 // CXX11-NEXT: 9: [B1.8] 854 // CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], [B1.12]+1, class argument_constructors::D) 855 // CXX11-NEXT: 11: [B1.10] (BindTemporary) 856 // CXX11-NEXT: 12: [B1.2]([B1.5], [B1.11]) 857 // CXX11-NEXT: 13: ~argument_constructors::D() (Temporary object destructor) 858 // CXX11-NEXT: 14: ~argument_constructors::D() (Temporary object destructor) 859 // CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.6]+0, class C) 860 // CXX17-NEXT: 4: argument_constructors::D() (CXXConstructExpr, [B1.5], [B1.6]+1, class argument_co 861 // CXX17-NEXT: 5: [B1.4] (BindTemporary) 862 // CXX17-NEXT: 6: [B1.2]([B1.3], [B1.5]) 863 // CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor) 864 void passTwoArguments() { 865 useCAndD(C(), D()); 866 } 867 868 // CHECK: void passArgumentByReference() 869 // CHECK: 1: useCByReference 870 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class C &)) 871 // CHECK-NEXT: 3: C() (CXXConstructExpr, [B1.5], class C) 872 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class C) 873 // CHECK-NEXT: 5: [B1.4] 874 // CHECK-NEXT: 6: [B1.2]([B1.5]) 875 void passArgumentByReference() { 876 useCByReference(C()); 877 } 878 879 // CHECK: void passArgumentWithDestructor() 880 // CHECK: 1: useD 881 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class argument_constructors::D)) 882 // CXX11-ELIDE-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], class argument_constructors::D) 883 // CXX11-NOELIDE-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_constructors::D) 884 // CXX11-NEXT: 4: [B1.3] (BindTemporary) 885 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 886 // CXX11-NEXT: 6: [B1.5] 887 // CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, class argument_constructors::D) 888 // CXX11-NEXT: 8: [B1.7] (BindTemporary) 889 // CXX11-NEXT: 9: [B1.2]([B1.8]) 890 // CXX11-NEXT: 10: ~argument_constructors::D() (Temporary object destructor) 891 // CXX11-NEXT: 11: ~argument_constructors::D() (Temporary object destructor) 892 // CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+0, class argument_constructors::D) 893 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 894 // CXX17-NEXT: 5: [B1.2]([B1.4]) 895 // CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) 896 void passArgumentWithDestructor() { 897 useD(D()); 898 } 899 900 // CHECK: void passArgumentWithDestructorByReference() 901 // CHECK: 1: useDByReference 902 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class argumen 903 // CHECK-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_c 904 // CHECK-NEXT: 4: [B1.3] (BindTemporary) 905 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 906 // CHECK-NEXT: 6: [B1.5] 907 // CHECK-NEXT: 7: [B1.2]([B1.6]) 908 // CHECK-NEXT: 8: ~argument_constructors::D() (Temporary object destructor) 909 void passArgumentWithDestructorByReference() { 910 useDByReference(D()); 911 } 912 913 // CHECK: void passArgumentIntoAnotherConstructor() 914 // CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) 915 // CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) 916 // CXX11-NEXT: 2: [B1.1] (BindTemporary) 917 // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 918 // CXX11-NEXT: 4: [B1.3] 919 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.7]+0, class argument_constructors::D) 920 // CXX11-NEXT: 6: [B1.5] (BindTemporary) 921 // CXX11-ELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], [B1.10], class argument_constructors::E) 922 // CXX11-NOELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], class argument_constructors::E) 923 // CXX11-NEXT: 8: argument_constructors::E([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E) 924 // CXX11-NEXT: 9: [B1.8] 925 // CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], class argument_constructors::E) 926 // CXX11-NEXT: 11: argument_constructors::E e = argument_constructors::E(argument_constructors::D()); 927 // CXX11-NEXT: 12: ~argument_constructors::D() (Temporary object destructor) 928 // CXX11-NEXT: 13: ~argument_constructors::D() (Temporary object destructor) 929 // CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.3]+0, class argument_constructors::D) 930 // CXX17-NEXT: 2: [B1.1] (BindTemporary) 931 // CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class argument_constructors::E) 932 // CXX17-NEXT: 4: argument_constructors::E([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E) 933 // CXX17-NEXT: 5: argument_constructors::E e = argument_constructors::E(argument_constructors::D()); 934 // CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) 935 void passArgumentIntoAnotherConstructor() { 936 E e = E(D()); 937 } 938 939 940 // CHECK: void passTwoArgumentsIntoAnotherConstructor() 941 // CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) 942 // CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) 943 // CXX11-NEXT: 2: [B1.1] (BindTemporary) 944 // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 945 // CXX11-NEXT: 4: [B1.3] 946 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class argument_constructors::D) 947 // CXX11-NEXT: 6: [B1.5] (BindTemporary) 948 // CXX11-ELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class argument_constructors::D) 949 // CXX11-NOELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], class argument_constructors::D) 950 // CXX11-NEXT: 8: [B1.7] (BindTemporary) 951 // CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 952 // CXX11-NEXT: 10: [B1.9] 953 // CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], [B1.13]+1, class argument_constructors::D) 954 // CXX11-NEXT: 12: [B1.11] (BindTemporary) 955 // CXX11-NEXT: 13: argument_constructors::E([B1.6], [B1.12]) (CXXConstructExpr, class argument_constructors::E) 956 // CXX11-NEXT: 14: ~argument_constructors::D() (Temporary object destructor) 957 // CXX11-NEXT: 15: ~argument_constructors::D() (Temporary object destructor) 958 // CXX11-NEXT: 16: ~argument_constructors::D() (Temporary object destructor) 959 // CXX11-NEXT: 17: ~argument_constructors::D() (Temporary object destructor) 960 // CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.5]+0, class argument_constructors::D) 961 // CXX17-NEXT: 2: [B1.1] (BindTemporary) 962 // CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+1, class argument_constructors::D) 963 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 964 // CXX17-NEXT: 5: argument_constructors::E([B1.2], [B1.4]) (CXXConstructExpr, class argument_constructors::E) 965 // CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) 966 // CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor) 967 void passTwoArgumentsIntoAnotherConstructor() { 968 E(D(), D()); 969 } 970 } // end namespace argument_constructors 971 972 namespace copy_elision_with_extra_arguments { 973 class C { 974 public: 975 C(); 976 C(const C &c, int x = 0); 977 }; 978 979 // CHECK: void testCopyElisionWhenCopyConstructorHasExtraArguments() 980 // CHECK: [B1] 981 // CXX11-ELIDE-NEXT: 1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.3], [B1.5], class copy_elision_with_extra_arguments::C) 982 // CXX11-NOELIDE-NEXT: 1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.3], class copy_elision_with_extra_arguments::C) 983 // CXX11-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class copy_elision_with_extra_arguments::C) 984 // CXX11-NEXT: 3: [B1.2] 985 // CXX11-NEXT: 4: 986 // CXX11-NEXT: 5: [B1.3] (CXXConstructExpr, [B1.6], class copy_elision_with_extra_arguments::C) 987 // CXX11-NEXT: 6: copy_elision_with_extra_arguments::C c = copy_elision_with_extra_arguments::C(); 988 // CXX17-NEXT: 1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.2], class copy_elision_with_extra_arguments::C) 989 // CXX17-NEXT: 2: copy_elision_with_extra_arguments::C c = copy_elision_with_extra_arguments::C(); 990 void testCopyElisionWhenCopyConstructorHasExtraArguments() { 991 C c = C(); 992 } 993 } // namespace copy_elision_with_extra_arguments 994 995 996 namespace operators { 997 class C { 998 public: 999 C(int); 1000 C &operator+(C Other); 1001 }; 1002 1003 // FIXME: Find construction context for the this-argument of the operator. 1004 // CHECK: void testOperators() 1005 // CHECK: [B1] 1006 // CHECK-NEXT: 1: operator+ 1007 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class operators::C &(*)(class o 1008 // CHECK-NEXT: 3: 1 1009 // CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], class operators::C) 1010 // CHECK-NEXT: 5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operato 1011 // CHECK-NEXT: 6: [B1.5] 1012 // CHECK-NEXT: 7: 2 1013 // CXX11-ELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], [B1.11], class operators::C) 1014 // CXX11-NOELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], class operators::C) 1015 // CXX11-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato 1016 // CXX11-NEXT: 10: [B1.9] 1017 // CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12]+1, class operators::C) 1018 // CXX11-NEXT: 12: [B1.6] + [B1.11] (OperatorCall) 1019 // CXX17-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10]+1, class operators::C) 1020 // CXX17-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato 1021 // CXX17-NEXT: 10: [B1.6] + [B1.9] (OperatorCall) 1022 void testOperators() { 1023 C(1) + C(2); 1024 } 1025 } // namespace operators 1026 1027 namespace variadic_function_arguments { 1028 class C { 1029 public: 1030 C(int); 1031 }; 1032 1033 int variadic(...); 1034 1035 // This code is quite exotic, so let's not test the CFG for it, 1036 // but only make sure we don't crash. 1037 void testCrashOnVariadicArgument() { 1038 C c(variadic(0 ? c : 0)); // no-crash 1039 } 1040 } // namespace variadic_function_arguments 1041 1042 // CHECK: void testTransparentInitListExprs() 1043 // CHECK: [B1] 1044 // CHECK-NEXT: 1: getC 1045 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class transparent_init_list_exprs::C (*)(void)) 1046 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5]) 1047 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 1048 // CXX11-NEXT: 4: [B1.3] 1049 // CXX11-NEXT: 5: {[B1.4]} (CXXConstructExpr, [B1.6], class transparent_init_list_exprs::C) 1050 // CXX11-NEXT: 6: transparent_init_list_exprs::C c{getC()}; 1051 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 1052 // CXX17-NEXT: 4: {[B1.3]} 1053 // CXX17-NEXT: 5: transparent_init_list_exprs::C c{getC()}; 1054 namespace transparent_init_list_exprs { 1055 class C {}; 1056 C getC(); 1057 void testTransparentInitListExprs() { 1058 C c{getC()}; 1059 } 1060 } // namespace transparent_init_list_exprs 1061