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,ELIDE,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,ELIDE,CXX17-ELIDE %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,NOELIDE,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,NOELIDE,CXX17-NOELIDE %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 // FIXME: There should be no temporary destructor in C++17. 416 // CHECK: return_stmt_with_dtor::D returnTemporary() 417 // CXX11-ELIDE: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class return_stmt_with_dtor::D) 418 // CXX11-NOELIDE: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], class return_stmt_with_dtor::D) 419 // CXX11-NEXT: 2: [B1.1] (BindTemporary) 420 // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D) 421 // CXX11-NEXT: 4: [B1.3] 422 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D) 423 // CXX11-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor) 424 // CXX11-NEXT: 7: return [B1.5]; 425 // CXX17: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.4], [B1.2], class return_stmt_w 426 // CXX17-NEXT: 2: [B1.1] (BindTemporary) 427 // CXX17-NEXT: 3: ~return_stmt_with_dtor::D() (Temporary object destructor) 428 // CXX17-NEXT: 4: return [B1.2]; 429 D returnTemporary() { 430 return D(); 431 } 432 433 // FIXME: There should be no temporary destructor in C++17. 434 // CHECK: void returnByValueIntoVariable() 435 // CHECK: 1: returnTemporary 436 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class return_stmt_with_dtor::D (*)(void)) 437 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7]) 438 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6]) 439 // CXX11-NEXT: 4: [B1.3] (BindTemporary) 440 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D) 441 // CXX11-NEXT: 6: [B1.5] 442 // CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], class return_stmt_with_dtor::D) 443 // CXX11-NEXT: 8: return_stmt_with_dtor::D d = returnTemporary(); 444 // CXX11-NEXT: 9: ~return_stmt_with_dtor::D() (Temporary object destructor) 445 // CXX11-NEXT: 10: [B1.8].~D() (Implicit destructor) 446 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5], [B1.4]) 447 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 448 // CXX17-NEXT: 5: return_stmt_with_dtor::D d = returnTemporary(); 449 // CXX17-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor) 450 // CXX17-NEXT: 7: [B1.5].~D() (Implicit destructor) 451 void returnByValueIntoVariable() { 452 D d = returnTemporary(); 453 } 454 455 } // end namespace return_stmt_with_dtor 456 457 namespace temporary_object_expr_without_dtors { 458 459 // TODO: Should provide construction context for the constructor, 460 // even if there is no specific trigger statement here. 461 // CHECK: void simpleTemporary() 462 // CHECK 1: C() (CXXConstructExpr, class C) 463 void simpleTemporary() { 464 C(); 465 } 466 467 // CHECK: void temporaryInCondition() 468 // CHECK: 1: C() (CXXConstructExpr, [B2.2], class C) 469 // CHECK-NEXT: 2: [B2.1] 470 // CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class C) 471 // CHECK-NEXT: 4: [B2.3].operator bool 472 // CHECK-NEXT: 5: [B2.3] 473 // CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) 474 // CHECK-NEXT: T: if [B2.6] 475 void temporaryInCondition() { 476 if (C()); 477 } 478 479 // CHECK: void temporaryInConditionVariable() 480 // CXX11-ELIDE: 1: C() (CXXConstructExpr, [B2.2], [B2.3], class C) 481 // CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B2.2], class C) 482 // CXX11-NEXT: 2: [B2.1] 483 // CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) 484 // CXX11-NEXT: 4: C c = C(); 485 // CXX11-NEXT: 5: c 486 // CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) 487 // CXX11-NEXT: 7: [B2.6].operator bool 488 // CXX11-NEXT: 8: [B2.6] 489 // CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 490 // CXX11-NEXT: T: if [B2.9] 491 // CXX17: 1: C() (CXXConstructExpr, [B2.2], class C) 492 // CXX17-NEXT: 2: C c = C(); 493 // CXX17-NEXT: 3: c 494 // CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) 495 // CXX17-NEXT: 5: [B2.4].operator bool 496 // CXX17-NEXT: 6: [B2.4] 497 // CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 498 // CXX17-NEXT: T: if [B2.7] 499 void temporaryInConditionVariable() { 500 if (C c = C()); 501 } 502 503 504 // CHECK: void temporaryInForLoopConditionVariable() 505 // CHECK: [B2] 506 // CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B2.2], [B2.3], class C) 507 // CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C) 508 // CXX11-NEXT: 2: [B2.1] 509 // CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) 510 // CXX11-NEXT: 4: C c2 = C(); 511 // CXX11-NEXT: 5: c2 512 // CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) 513 // CXX11-NEXT: 7: [B2.6].operator bool 514 // CXX11-NEXT: 8: [B2.6] 515 // CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 516 // CXX11-NEXT: T: for (...; [B2.9]; ) 517 // CXX17-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C) 518 // CXX17-NEXT: 2: C c2 = C(); 519 // CXX17-NEXT: 3: c2 520 // CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) 521 // CXX17-NEXT: 5: [B2.4].operator bool 522 // CXX17-NEXT: 6: [B2.4] 523 // CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 524 // CXX17-NEXT: T: for (...; [B2.7]; ) 525 // CHECK: [B3] 526 // CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B3.2], [B3.3], class C) 527 // CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C) 528 // CXX11-NEXT: 2: [B3.1] 529 // CXX11-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.4], class C) 530 // CXX11-NEXT: 4: C c1 = C(); 531 // CXX17-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C) 532 // CXX17-NEXT: 2: C c1 = C(); 533 void temporaryInForLoopConditionVariable() { 534 for (C c1 = C(); C c2 = C(); ); 535 } 536 537 538 // CHECK: void temporaryInWhileLoopConditionVariable() 539 // CXX11-ELIDE: 1: C() (CXXConstructExpr, [B2.2], [B2.3], class C) 540 // CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B2.2], class C) 541 // CXX11-NEXT: 2: [B2.1] 542 // CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) 543 // CXX11-NEXT: 4: C c = C(); 544 // CXX11-NEXT: 5: c 545 // CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) 546 // CXX11-NEXT: 7: [B2.6].operator bool 547 // CXX11-NEXT: 8: [B2.6] 548 // CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 549 // CXX11-NEXT: T: while [B2.9] 550 // CXX17: 1: C() (CXXConstructExpr, [B2.2], class C) 551 // CXX17-NEXT: 2: C c = C(); 552 // CXX17-NEXT: 3: c 553 // CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) 554 // CXX17-NEXT: 5: [B2.4].operator bool 555 // CXX17-NEXT: 6: [B2.4] 556 // CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 557 // CXX17-NEXT: T: while [B2.7] 558 void temporaryInWhileLoopConditionVariable() { 559 while (C c = C()); 560 } 561 562 } // end namespace temporary_object_expr_without_dtors 563 564 namespace temporary_object_expr_with_dtors { 565 566 class D { 567 public: 568 D(); 569 D(int); 570 ~D(); 571 572 static D get(); 573 574 operator bool() const; 575 }; 576 577 // CHECK: void simpleTemporary() 578 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D) 579 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 580 // CHECK-NEXT: 3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 581 void simpleTemporary() { 582 D(); 583 } 584 585 // CHECK: void temporaryInCondition() 586 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], [B2.3], class temporary_object_expr_with_dtors::D) 587 // CHECK-NEXT: 2: [B2.1] (BindTemporary) 588 // CHECK-NEXT: 3: [B2.2] 589 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 590 // CHECK-NEXT: 5: [B2.4].operator bool 591 // CHECK-NEXT: 6: [B2.4] 592 // CHECK-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) 593 // CHECK-NEXT: 8: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 594 // CHECK-NEXT: T: if [B2.7] 595 void temporaryInCondition() { 596 if (D()); 597 } 598 599 // CHECK: void referenceVariableWithConstructor() 600 // CHECK: 1: 0 601 // CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.4], const class temporary_object_expr_with_dtors::D) 602 // CHECK-NEXT: 3: [B1.2] (BindTemporary) 603 // CHECK-NEXT: 4: [B1.3] 604 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0); 605 // CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor) 606 void referenceVariableWithConstructor() { 607 const D &d(0); 608 } 609 610 // CHECK: void referenceVariableWithInitializer() 611 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.4], class temporary_object_expr_with_dtors::D) 612 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 613 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 614 // CHECK-NEXT: 4: [B1.3] 615 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D(); 616 // CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor) 617 void referenceVariableWithInitializer() { 618 const D &d = D(); 619 } 620 621 // CHECK: void referenceVariableWithTernaryOperator(bool coin) 622 // CXX11: [B1] 623 // CXX11-NEXT: 1: [B4.4].~D() (Implicit destructor) 624 // CXX11: [B2] 625 // CXX11-NEXT: 1: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 626 // CXX11: [B3] 627 // CXX11-NEXT: 1: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 628 // CXX11: [B4] 629 // CXX11-NEXT: 1: [B7.2] ? [B5.8] : [B6.8] 630 // CXX11-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 631 // CXX11-NEXT: 3: [B4.2] 632 // CXX11-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0); 633 // CXX11-NEXT: T: (Temp Dtor) [B6.3] 634 // CXX11: [B5] 635 // CXX11-NEXT: 1: D::get 636 // CXX11-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) 637 // CXX11-ELIDE-NEXT: 3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6], [B5.7]) 638 // CXX11-NOELIDE-NEXT: 3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6]) 639 // CXX11-NEXT: 4: [B5.3] (BindTemporary) 640 // CXX11-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 641 // CXX11-NEXT: 6: [B5.5] 642 // CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D) 643 // CXX11-NEXT: 8: [B5.7] (BindTemporary) 644 // CXX11: [B6] 645 // CXX11-NEXT: 1: 0 646 // CXX11-ELIDE-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], [B6.7], class temporary_object_expr_with_dtors::D) 647 // CXX11-NOELIDE-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], class temporary_object_expr_with_dtors::D) 648 // CXX11-NEXT: 3: [B6.2] (BindTemporary) 649 // CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 650 // CXX11-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 651 // CXX11-NEXT: 6: [B6.5] 652 // CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D) 653 // CXX11-NEXT: 8: [B6.7] (BindTemporary) 654 // CXX11: [B7] 655 // CXX11-NEXT: 1: coin 656 // CXX11-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) 657 // CXX11-NEXT: T: [B7.2] ? ... : ... 658 // CXX17: [B1] 659 // CXX17-NEXT: 1: [B4.2] ? [B2.4] : [B3.4] 660 // CXX17-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 661 // CXX17-NEXT: 3: [B1.2] 662 // CXX17-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0); 663 // CXX17-NEXT: 5: [B1.4].~D() (Implicit destructor) 664 // CXX17: [B2] 665 // CXX17-NEXT: 1: D::get 666 // CXX17-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) 667 // CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3]) 668 // CXX17-NEXT: 4: [B2.3] (BindTemporary) 669 // CXX17: [B3] 670 // CXX17-NEXT: 1: 0 671 // CXX17-NEXT: 2: [B3.1] (CXXConstructExpr, [B1.3], class temporary_object_expr_with_dtors::D) 672 // CXX17-NEXT: 3: [B3.2] (BindTemporary) 673 // CXX17-NEXT: 4: temporary_object_expr_with_dtors::D([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 674 // CXX17: [B4] 675 // CXX17-NEXT: 1: coin 676 // CXX17-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 677 // CXX17-NEXT: T: [B4.2] ? ... : ... 678 void referenceVariableWithTernaryOperator(bool coin) { 679 const D &d = coin ? D::get() : D(0); 680 } 681 682 // CHECK: void referenceWithFunctionalCast() 683 // CHECK: 1: 1 684 // CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.5], class temporary_object_expr_with_dtors::D) 685 // CHECK-NEXT: 3: [B1.2] (BindTemporary) 686 // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B1.3]) (CXXFunctionalCastExpr, ConstructorCon 687 // CHECK-NEXT: 5: [B1.4] 688 // CHECK-NEXT: 6: temporary_object_expr_with_dtors::D &&d = temporary_object_expr_with_dtors::D(1); 689 // CHECK-NEXT: 7: [B1.6].~D() (Implicit destructor) 690 void referenceWithFunctionalCast() { 691 D &&d = D(1); 692 } 693 694 // Test the condition constructor, we don't care about branch constructors here. 695 // CHECK: void constructorInTernaryCondition() 696 // CXX11: 1: 1 697 // CXX11-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], [B7.5], class temporary_object_expr_with_dtors::D) 698 // CXX11-NEXT: 3: [B7.2] (BindTemporary) 699 // CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B7.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 700 // CXX11-NEXT: 5: [B7.4] 701 // CXX11-NEXT: 6: [B7.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 702 // CXX11-NEXT: 7: [B7.6].operator bool 703 // CXX11-NEXT: 8: [B7.6] 704 // CXX11-NEXT: 9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 705 // CXX11-NEXT: T: [B7.9] ? ... : ... 706 // CXX17: 1: 1 707 // CXX17-NEXT: 2: [B4.1] (CXXConstructExpr, [B4.3], [B4.5], class temporary_object_expr_with_dtors::D) 708 // CXX17-NEXT: 3: [B4.2] (BindTemporary) 709 // CXX17-NEXT: 4: temporary_object_expr_with_dtors::D([B4.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 710 // CXX17-NEXT: 5: [B4.4] 711 // CXX17-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 712 // CXX17-NEXT: 7: [B4.6].operator bool 713 // CXX17-NEXT: 8: [B4.6] 714 // CXX17-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) 715 // CXX17-NEXT: T: [B4.9] ? ... : ... 716 void constructorInTernaryCondition() { 717 const D &d = D(1) ? D(2) : D(3); 718 } 719 720 } // end namespace temporary_object_expr_with_dtors 721 722 namespace implicit_constructor_conversion { 723 724 class A {}; 725 A get(); 726 727 class B { 728 public: 729 B(const A &); 730 ~B() {} 731 }; 732 733 // CHECK: void implicitConstructionConversionFromTemporary() 734 // CHECK: 1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A) 735 // CXX11-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 736 // CXX11-NEXT: 3: [B1.2] 737 // CXX11-ELIDE-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], [B1.9], class implicit_constructor_conversion::B) 738 // CXX11-NOELIDE-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], class implicit_constructor_conversion::B) 739 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 740 // CXX11-NEXT: 6: [B1.5] (BindTemporary) 741 // CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 742 // CXX11-NEXT: 8: [B1.7] 743 // CXX11-NEXT: 9: [B1.8] (CXXConstructExpr, [B1.10], class implicit_constructor_conversion::B) 744 // CXX11-NEXT: 10: implicit_constructor_conversion::B b = implicit_constructor_conversion::A(); 745 // CXX11-NEXT: 11: ~implicit_constructor_conversion::B() (Temporary object destructor) 746 // CXX11-NEXT: 12: [B1.10].~B() (Implicit destructor) 747 // CXX17-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 748 // CXX17-NEXT: 3: [B1.2] 749 // CXX17-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], class implicit_constructor_conversion::B) 750 // CXX17-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 751 // CXX17-NEXT: 6: implicit_constructor_conversion::B b = implicit_constructor_conversion::A(); 752 // CXX17-NEXT: 7: [B1.6].~B() (Implicit destructor) 753 void implicitConstructionConversionFromTemporary() { 754 B b = A(); 755 } 756 757 // CHECK: void implicitConstructionConversionFromFunctionValue() 758 // CHECK: 1: get 759 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conversion::A (*)(void)) 760 // CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 761 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 762 // CHECK-NEXT: 5: [B1.4] 763 // CXX11-ELIDE-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class implicit_constructor_conversion::B) 764 // CXX11-NOELIDE-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], class implicit_constructor_conversion::B) 765 // CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 766 // CXX11-NEXT: 8: [B1.7] (BindTemporary) 767 // CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 768 // CXX11-NEXT: 10: [B1.9] 769 // CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], class implicit_constructor_conversion::B) 770 // CXX11-NEXT: 12: implicit_constructor_conversion::B b = get(); 771 // CXX11-NEXT: 13: ~implicit_constructor_conversion::B() (Temporary object destructor) 772 // CXX11-NEXT: 14: [B1.12].~B() (Implicit destructor) 773 // CXX17-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], class implicit_constructor_conversion::B) 774 // CXX17-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 775 // CXX17-NEXT: 8: implicit_constructor_conversion::B b = get(); 776 // CXX17-NEXT: 9: [B1.8].~B() (Implicit destructor) 777 void implicitConstructionConversionFromFunctionValue() { 778 B b = get(); 779 } 780 781 // CHECK: void implicitConstructionConversionFromTemporaryWithLifetimeExtension() 782 // CHECK: 1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A) 783 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 784 // CHECK-NEXT: 3: [B1.2] 785 // CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.7], class implicit_constructor_conversion::B) 786 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B) 787 // CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 788 // CHECK-NEXT: 7: [B1.6] 789 // CHECK-NEXT: 8: const implicit_constructor_conversion::B &b = implicit_constructor_conversion::A(); 790 // CHECK-NEXT: 9: [B1.8].~B() (Implicit destructor) 791 void implicitConstructionConversionFromTemporaryWithLifetimeExtension() { 792 const B &b = A(); 793 } 794 795 // CHECK: void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() 796 // CHECK: 1: get 797 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver 798 // CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 799 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A) 800 // CHECK-NEXT: 5: [B1.4] 801 // CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.9], class implicit_constructor_conversion::B) 802 // CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers 803 // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B) 804 // CHECK-NEXT: 9: [B1.8] 805 // CHECK-NEXT: 10: const implicit_constructor_conversion::B &b = get(); 806 // CHECK-NEXT: 11: [B1.10].~B() (Implicit destructor) 807 void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() { 808 const B &b = get(); // no-crash 809 } 810 811 } // end namespace implicit_constructor_conversion 812 813 namespace argument_constructors { 814 class D { 815 public: 816 D(); 817 ~D(); 818 }; 819 820 class E { 821 public: 822 E(D d); 823 E(D d1, D d2); 824 }; 825 826 void useC(C c); 827 void useCByReference(const C &c); 828 void useD(D d); 829 void useDByReference(const D &d); 830 void useCAndD(C c, D d); 831 832 // CHECK: void passArgument() 833 // CHECK: 1: useC 834 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C)) 835 // CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], class C) 836 // CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C) 837 // CXX11-NEXT: 4: [B1.3] 838 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6]+0, class C) 839 // CXX11-NEXT: 6: [B1.2]([B1.5]) 840 // CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.4]+0, class C) 841 // CXX17-NEXT: 4: [B1.2]([B1.3]) 842 void passArgument() { 843 useC(C()); 844 } 845 846 // CHECK: void passTwoArguments() 847 // CHECK: [B1] 848 // CHECK-NEXT: 1: useCAndD 849 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C, class argument_constructors::D)) 850 // CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], class C) 851 // CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], class C) 852 // CXX11-NEXT: 4: [B1.3] 853 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.12]+0, class C) 854 // CXX11-ELIDE-NEXT: 6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], [B1.10], class argument_constructors::D) 855 // CXX11-NOELIDE-NEXT: 6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], class argument_constructors::D) 856 // CXX11-NEXT: 7: [B1.6] (BindTemporary) 857 // CXX11-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 858 // CXX11-NEXT: 9: [B1.8] 859 // CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], [B1.12]+1, class argument_constructors::D) 860 // CXX11-NEXT: 11: [B1.10] (BindTemporary) 861 // CXX11-NEXT: 12: [B1.2]([B1.5], [B1.11]) 862 // CXX11-NEXT: 13: ~argument_constructors::D() (Temporary object destructor) 863 // CXX11-NEXT: 14: ~argument_constructors::D() (Temporary object destructor) 864 // CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.6]+0, class C) 865 // CXX17-NEXT: 4: argument_constructors::D() (CXXConstructExpr, [B1.5], [B1.6]+1, class argument_co 866 // CXX17-NEXT: 5: [B1.4] (BindTemporary) 867 // CXX17-NEXT: 6: [B1.2]([B1.3], [B1.5]) 868 // CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor) 869 void passTwoArguments() { 870 useCAndD(C(), D()); 871 } 872 873 // CHECK: void passArgumentByReference() 874 // CHECK: 1: useCByReference 875 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class C &)) 876 // CHECK-NEXT: 3: C() (CXXConstructExpr, [B1.5], class C) 877 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class C) 878 // CHECK-NEXT: 5: [B1.4] 879 // CHECK-NEXT: 6: [B1.2]([B1.5]) 880 void passArgumentByReference() { 881 useCByReference(C()); 882 } 883 884 // CHECK: void passArgumentWithDestructor() 885 // CHECK: 1: useD 886 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class argument_constructors::D)) 887 // CXX11-ELIDE-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], class argument_constructors::D) 888 // CXX11-NOELIDE-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_constructors::D) 889 // CXX11-NEXT: 4: [B1.3] (BindTemporary) 890 // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 891 // CXX11-NEXT: 6: [B1.5] 892 // CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, class argument_constructors::D) 893 // CXX11-NEXT: 8: [B1.7] (BindTemporary) 894 // CXX11-NEXT: 9: [B1.2]([B1.8]) 895 // CXX11-NEXT: 10: ~argument_constructors::D() (Temporary object destructor) 896 // CXX11-NEXT: 11: ~argument_constructors::D() (Temporary object destructor) 897 // CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+0, class argument_constructors::D) 898 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 899 // CXX17-NEXT: 5: [B1.2]([B1.4]) 900 // CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) 901 void passArgumentWithDestructor() { 902 useD(D()); 903 } 904 905 // CHECK: void passArgumentWithDestructorByReference() 906 // CHECK: 1: useDByReference 907 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class argumen 908 // CHECK-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_c 909 // CHECK-NEXT: 4: [B1.3] (BindTemporary) 910 // CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 911 // CHECK-NEXT: 6: [B1.5] 912 // CHECK-NEXT: 7: [B1.2]([B1.6]) 913 // CHECK-NEXT: 8: ~argument_constructors::D() (Temporary object destructor) 914 void passArgumentWithDestructorByReference() { 915 useDByReference(D()); 916 } 917 918 // CHECK: void passArgumentIntoAnotherConstructor() 919 // CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) 920 // CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) 921 // CXX11-NEXT: 2: [B1.1] (BindTemporary) 922 // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 923 // CXX11-NEXT: 4: [B1.3] 924 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.7]+0, class argument_constructors::D) 925 // CXX11-NEXT: 6: [B1.5] (BindTemporary) 926 // CXX11-ELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], [B1.10], class argument_constructors::E) 927 // CXX11-NOELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], class argument_constructors::E) 928 // CXX11-NEXT: 8: argument_constructors::E([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E) 929 // CXX11-NEXT: 9: [B1.8] 930 // CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], class argument_constructors::E) 931 // CXX11-NEXT: 11: argument_constructors::E e = argument_constructors::E(argument_constructors::D()); 932 // CXX11-NEXT: 12: ~argument_constructors::D() (Temporary object destructor) 933 // CXX11-NEXT: 13: ~argument_constructors::D() (Temporary object destructor) 934 // CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.3]+0, class argument_constructors::D) 935 // CXX17-NEXT: 2: [B1.1] (BindTemporary) 936 // CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class argument_constructors::E) 937 // CXX17-NEXT: 4: argument_constructors::E([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E) 938 // CXX17-NEXT: 5: argument_constructors::E e = argument_constructors::E(argument_constructors::D()); 939 // CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) 940 void passArgumentIntoAnotherConstructor() { 941 E e = E(D()); 942 } 943 944 945 // CHECK: void passTwoArgumentsIntoAnotherConstructor() 946 // CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) 947 // CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) 948 // CXX11-NEXT: 2: [B1.1] (BindTemporary) 949 // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 950 // CXX11-NEXT: 4: [B1.3] 951 // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class argument_constructors::D) 952 // CXX11-NEXT: 6: [B1.5] (BindTemporary) 953 // CXX11-ELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class argument_constructors::D) 954 // CXX11-NOELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], class argument_constructors::D) 955 // CXX11-NEXT: 8: [B1.7] (BindTemporary) 956 // CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class argument_constructors::D) 957 // CXX11-NEXT: 10: [B1.9] 958 // CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], [B1.13]+1, class argument_constructors::D) 959 // CXX11-NEXT: 12: [B1.11] (BindTemporary) 960 // CXX11-NEXT: 13: argument_constructors::E([B1.6], [B1.12]) (CXXConstructExpr, class argument_constructors::E) 961 // CXX11-NEXT: 14: ~argument_constructors::D() (Temporary object destructor) 962 // CXX11-NEXT: 15: ~argument_constructors::D() (Temporary object destructor) 963 // CXX11-NEXT: 16: ~argument_constructors::D() (Temporary object destructor) 964 // CXX11-NEXT: 17: ~argument_constructors::D() (Temporary object destructor) 965 // CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.5]+0, class argument_constructors::D) 966 // CXX17-NEXT: 2: [B1.1] (BindTemporary) 967 // CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+1, class argument_constructors::D) 968 // CXX17-NEXT: 4: [B1.3] (BindTemporary) 969 // CXX17-NEXT: 5: argument_constructors::E([B1.2], [B1.4]) (CXXConstructExpr, class argument_constructors::E) 970 // CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) 971 // CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor) 972 void passTwoArgumentsIntoAnotherConstructor() { 973 E(D(), D()); 974 } 975 } // end namespace argument_constructors 976 977 namespace copy_elision_with_extra_arguments { 978 class C { 979 public: 980 C(); 981 C(const C &c, int x = 0); 982 }; 983 984 // CHECK: void testCopyElisionWhenCopyConstructorHasExtraArguments() 985 // CHECK: [B1] 986 // CXX11-ELIDE-NEXT: 1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.3], [B1.5], class copy_elision_with_extra_arguments::C) 987 // CXX11-NOELIDE-NEXT: 1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.3], class copy_elision_with_extra_arguments::C) 988 // CXX11-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class copy_elision_with_extra_arguments::C) 989 // CXX11-NEXT: 3: [B1.2] 990 // CXX11-NEXT: 4: 991 // CXX11-NEXT: 5: [B1.3] (CXXConstructExpr, [B1.6], class copy_elision_with_extra_arguments::C) 992 // CXX11-NEXT: 6: copy_elision_with_extra_arguments::C c = copy_elision_with_extra_arguments::C(); 993 // CXX17-NEXT: 1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.2], class copy_elision_with_extra_arguments::C) 994 // CXX17-NEXT: 2: copy_elision_with_extra_arguments::C c = copy_elision_with_extra_arguments::C(); 995 void testCopyElisionWhenCopyConstructorHasExtraArguments() { 996 C c = C(); 997 } 998 } // namespace copy_elision_with_extra_arguments 999 1000 1001 namespace operators { 1002 class C { 1003 public: 1004 C(int); 1005 C &operator+(C Other); 1006 }; 1007 1008 // FIXME: Find construction context for the this-argument of the operator. 1009 // CHECK: void testOperators() 1010 // CHECK: [B1] 1011 // CHECK-NEXT: 1: operator+ 1012 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class operators::C &(*)(class o 1013 // CHECK-NEXT: 3: 1 1014 // CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], class operators::C) 1015 // CHECK-NEXT: 5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operato 1016 // CHECK-NEXT: 6: [B1.5] 1017 // CHECK-NEXT: 7: 2 1018 // CXX11-ELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], [B1.11], class operators::C) 1019 // CXX11-NOELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], class operators::C) 1020 // CXX11-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato 1021 // CXX11-NEXT: 10: [B1.9] 1022 // CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12]+1, class operators::C) 1023 // CXX11-NEXT: 12: [B1.6] + [B1.11] (OperatorCall) 1024 // CXX17-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10]+1, class operators::C) 1025 // CXX17-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato 1026 // CXX17-NEXT: 10: [B1.6] + [B1.9] (OperatorCall) 1027 void testOperators() { 1028 C(1) + C(2); 1029 } 1030 } // namespace operators 1031 1032 namespace variadic_function_arguments { 1033 class C { 1034 public: 1035 C(int); 1036 }; 1037 1038 int variadic(...); 1039 1040 // This code is quite exotic, so let's not test the CFG for it, 1041 // but only make sure we don't crash. 1042 void testCrashOnVariadicArgument() { 1043 C c(variadic(0 ? c : 0)); // no-crash 1044 } 1045 } // namespace variadic_function_arguments 1046 1047 // CHECK: void testTransparentInitListExprs() 1048 // CHECK: [B1] 1049 // CHECK-NEXT: 1: getC 1050 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class transparent_init_list_exprs::C (*)(void)) 1051 // CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5]) 1052 // CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4]) 1053 // CXX11-NEXT: 4: [B1.3] 1054 // CXX11-NEXT: 5: {[B1.4]} (CXXConstructExpr, [B1.6], class transparent_init_list_exprs::C) 1055 // CXX11-NEXT: 6: transparent_init_list_exprs::C c{getC()}; 1056 // CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5]) 1057 // CXX17-NEXT: 4: {[B1.3]} 1058 // CXX17-NEXT: 5: transparent_init_list_exprs::C c{getC()}; 1059 namespace transparent_init_list_exprs { 1060 class C {}; 1061 C getC(); 1062 void testTransparentInitListExprs() { 1063 C c{getC()}; 1064 } 1065 } // namespace transparent_init_list_exprs 1066