1 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 -w %s > %t 2>&1 2 // RUN: FileCheck --input-file=%t %s 3 4 class C { 5 public: 6 C(); 7 C(C *); 8 C(int, int); 9 10 static C get(); 11 operator bool() const; 12 }; 13 14 typedef __typeof(sizeof(int)) size_t; 15 void *operator new(size_t size, void *placement); 16 17 namespace operator_new { 18 19 // CHECK: void operatorNewWithConstructor() 20 // CHECK: 1: CFGNewAllocator(C *) 21 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 22 // CHECK-NEXT: 3: new C([B1.2]) 23 void operatorNewWithConstructor() { 24 new C(); 25 } 26 27 // CHECK: void operatorNewWithConstructorWithOperatorNewWithContstructor() 28 // CHECK: 1: CFGNewAllocator(C *) 29 // CHECK-NEXT: 2: CFGNewAllocator(C *) 30 // CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], class C) 31 // CHECK-NEXT: 4: new C([B1.3]) 32 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 33 // CHECK-NEXT: 6: new C([B1.5]) 34 void operatorNewWithConstructorWithOperatorNewWithContstructor() { 35 new C(new C()); 36 } 37 38 // CHECK: void operatorPlacementNewWithConstructorWithinPlacementArgument() 39 // CHECK: 1: CFGNewAllocator(C *) 40 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 41 // CHECK-NEXT: 3: new C([B1.2]) 42 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *) 43 // CHECK-NEXT: 5: CFGNewAllocator(C *) 44 // CHECK-NEXT: 6: (CXXConstructExpr, [B1.7], class C) 45 // CHECK-NEXT: 7: new ([B1.4]) C([B1.6]) 46 void operatorPlacementNewWithConstructorWithinPlacementArgument() { 47 new (new C()) C(); 48 } 49 50 } // namespace operator_new 51 52 namespace decl_stmt { 53 54 // CHECK: void simpleVariable() 55 // CHECK: 1: (CXXConstructExpr, [B1.2], class C) 56 // CHECK-NEXT: 2: C c; 57 void simpleVariable() { 58 C c; 59 } 60 61 // CHECK: void simpleVariableWithBraces() 62 // CHECK: 1: {} (CXXConstructExpr, [B1.2], class C) 63 // CHECK-NEXT: 2: C c{}; 64 void simpleVariableWithBraces() { 65 C c{}; 66 } 67 68 // CHECK: void simpleVariableWithConstructorArgument() 69 // CHECK: 1: 0 70 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 71 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C) 72 // CHECK-NEXT: 4: C c(0); 73 void simpleVariableWithConstructorArgument() { 74 C c(0); 75 } 76 77 // CHECK: void simpleVariableWithOperatorNewInConstructorArgument() 78 // CHECK: 1: CFGNewAllocator(C *) 79 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 80 // CHECK-NEXT: 3: new C([B1.2]) 81 // CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.5], class C) 82 // CHECK-NEXT: 5: C c(new C()); 83 void simpleVariableWithOperatorNewInConstructorArgument() { 84 C c(new C()); 85 } 86 87 // CHECK: void simpleVariableWithOperatorNewInBraces() 88 // CHECK: 1: CFGNewAllocator(C *) 89 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 90 // CHECK-NEXT: 3: new C([B1.2]) 91 // CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], class C) 92 // CHECK-NEXT: 5: C c{new C()}; 93 void simpleVariableWithOperatorNewInBraces() { 94 C c{new C()}; 95 } 96 97 // CHECK: void simpleVariableInitializedByValue() 98 // CHECK: 1: C::get 99 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 100 // CHECK-NEXT: 3: [B1.2]() 101 // CHECK-NEXT: 4: [B1.3] 102 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 103 // CHECK-NEXT: 6: C c = C::get(); 104 void simpleVariableInitializedByValue() { 105 C c = C::get(); 106 } 107 108 // CHECK: void simpleVariableWithTernaryOperator(bool coin) 109 // CHECK: [B1] 110 // CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6] 111 // CHECK-NEXT: 2: [B1.1] 112 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C) 113 // CHECK-NEXT: 4: C c = coin ? C::get() : C(0); 114 // CHECK: [B2] 115 // CHECK-NEXT: 1: C::get 116 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 117 // CHECK-NEXT: 3: [B2.2]() 118 // CHECK-NEXT: 4: [B2.3] 119 // CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], class C) 120 // CHECK: [B3] 121 // CHECK-NEXT: 1: 0 122 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *) 123 // CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C) 124 // CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 125 // CHECK-NEXT: 5: [B3.4] 126 // CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], class C) 127 // CHECK: [B4] 128 // CHECK-NEXT: 1: coin 129 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 130 // CHECK-NEXT: T: [B4.2] ? ... : ... 131 void simpleVariableWithTernaryOperator(bool coin) { 132 C c = coin ? C::get() : C(0); 133 } 134 135 // CHECK: void simpleVariableWithElidableCopy() 136 // CHECK: 1: 0 137 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 138 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C) 139 // CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 140 // CHECK-NEXT: 5: [B1.4] 141 // CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], class C) 142 // CHECK-NEXT: 7: C c = C(0); 143 void simpleVariableWithElidableCopy() { 144 C c = C(0); 145 } 146 147 // CHECK: void referenceVariableWithConstructor() 148 // CHECK: 1: 0 149 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 150 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], const class C) 151 // CHECK-NEXT: 4: [B1.3] 152 // CHECK-NEXT: 5: const C &c(0); 153 void referenceVariableWithConstructor() { 154 const C &c(0); 155 } 156 157 // CHECK: void referenceVariableWithInitializer() 158 // CHECK: 1: C() (CXXConstructExpr, [B1.3], class C) 159 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C) 160 // CHECK-NEXT: 3: [B1.2] 161 // CHECK-NEXT: 4: const C &c = C(); 162 void referenceVariableWithInitializer() { 163 const C &c = C(); 164 } 165 166 // CHECK: void referenceVariableWithTernaryOperator(bool coin) 167 // CHECK: [B1] 168 // CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6] 169 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C) 170 // CHECK-NEXT: 3: [B1.2] 171 // CHECK-NEXT: 4: const C &c = coin ? C::get() : C(0); 172 // CHECK: [B2] 173 // CHECK-NEXT: 1: C::get 174 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 175 // CHECK-NEXT: 3: [B2.2]() 176 // CHECK-NEXT: 4: [B2.3] 177 // CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.3], class C) 178 // CHECK: [B3] 179 // CHECK-NEXT: 1: 0 180 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *) 181 // CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C) 182 // CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 183 // CHECK-NEXT: 5: [B3.4] 184 // CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.3], class C) 185 // CHECK: [B4] 186 // CHECK-NEXT: 1: coin 187 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) 188 // CHECK-NEXT: T: [B4.2] ? ... : ... 189 void referenceVariableWithTernaryOperator(bool coin) { 190 const C &c = coin ? C::get() : C(0); 191 } 192 193 } // end namespace decl_stmt 194 195 namespace ctor_initializers { 196 197 class D: public C { 198 C c1; 199 200 public: 201 202 // CHECK: D() 203 // CHECK: 1: (CXXConstructExpr, C() (Base initializer), class C) 204 // CHECK-NEXT: 2: C([B1.1]) (Base initializer) 205 // CHECK-NEXT: 3: CFGNewAllocator(C *) 206 // CHECK-NEXT: 4: (CXXConstructExpr, [B1.5], class C) 207 // CHECK-NEXT: 5: new C([B1.4]) 208 // CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, c1([B1.5]) (Member initializer), class C) 209 // CHECK-NEXT: 7: c1([B1.6]) (Member initializer) 210 D(): C(), c1(new C()) {} 211 212 // CHECK: D(int) 213 // CHECK: 1: (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D) 214 // CHECK-NEXT: 2: D([B1.1]) (Delegating initializer) 215 D(int): D() {} 216 217 // CHECK: D(double) 218 // CHECK: 1: C::get 219 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 220 // CHECK-NEXT: 3: [B1.2]() 221 // CHECK-NEXT: 4: [B1.3] 222 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), class C) 223 // CHECK-NEXT: 6: C([B1.5]) (Base initializer) 224 // CHECK-NEXT: 7: CFGNewAllocator(C *) 225 // CHECK-NEXT: 8: C::get 226 // CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 227 // CHECK-NEXT: 10: [B1.9]() 228 // CHECK-NEXT: 11: [B1.10] 229 // CHECK-NEXT: 12: [B1.11] (CXXConstructExpr, [B1.13], class C) 230 // CHECK-NEXT: 13: new C([B1.12]) 231 // CHECK-NEXT: 14: [B1.13] (CXXConstructExpr, c1([B1.13]) (Member initializer), class C) 232 // CHECK-NEXT: 15: c1([B1.14]) (Member initializer) 233 D(double): C(C::get()), c1(new C(C::get())) {} 234 }; 235 236 } // end namespace ctor_initializers 237 238 namespace return_stmt_without_dtor { 239 240 // CHECK: C returnVariable() 241 // CHECK: 1: (CXXConstructExpr, [B1.2], class C) 242 // CHECK-NEXT: 2: C c; 243 // CHECK-NEXT: 3: c 244 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, class C) 245 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 246 // CHECK-NEXT: 6: return [B1.5]; 247 C returnVariable() { 248 C c; 249 return c; 250 } 251 252 // CHECK: C returnEmptyBraces() 253 // CHECK: 1: {} (CXXConstructExpr, [B1.2], class C) 254 // CHECK-NEXT: 2: return [B1.1]; 255 C returnEmptyBraces() { 256 return {}; 257 } 258 259 // CHECK: C returnBracesWithOperatorNew() 260 // CHECK: 1: CFGNewAllocator(C *) 261 // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C) 262 // CHECK-NEXT: 3: new C([B1.2]) 263 // CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], class C) 264 // CHECK-NEXT: 5: return [B1.4]; 265 C returnBracesWithOperatorNew() { 266 return {new C()}; 267 } 268 269 // CHECK: C returnBracesWithMultipleItems() 270 // CHECK: 1: 123 271 // CHECK-NEXT: 2: 456 272 // CHECK-NEXT: 3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], class C) 273 // CHECK-NEXT: 4: return [B1.3]; 274 C returnBracesWithMultipleItems() { 275 return {123, 456}; 276 } 277 278 // CHECK: C returnTemporary() 279 // CHECK: 1: C() (CXXConstructExpr, [B1.2], class C) 280 // CHECK-NEXT: 2: [B1.1] 281 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C) 282 // CHECK-NEXT: 4: return [B1.3]; 283 C returnTemporary() { 284 return C(); 285 } 286 287 // CHECK: C returnTemporaryWithArgument() 288 // CHECK: 1: nullptr 289 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *) 290 // CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C) 291 // CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 292 // CHECK-NEXT: 5: [B1.4] 293 // CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], class C) 294 // CHECK-NEXT: 7: return [B1.6]; 295 C returnTemporaryWithArgument() { 296 return C(nullptr); 297 } 298 299 // CHECK: C returnTemporaryConstructedByFunction() 300 // CHECK: 1: C::get 301 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 302 // CHECK-NEXT: 3: [B1.2]() 303 // CHECK-NEXT: 4: [B1.3] 304 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C) 305 // CHECK-NEXT: 6: return [B1.5]; 306 C returnTemporaryConstructedByFunction() { 307 return C::get(); 308 } 309 310 // CHECK: C returnChainOfCopies() 311 // CHECK: 1: C::get 312 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) 313 // CHECK-NEXT: 3: [B1.2]() 314 // CHECK-NEXT: 4: [B1.3] 315 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class C) 316 // CHECK-NEXT: 6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, class C) 317 // CHECK-NEXT: 7: [B1.6] 318 // CHECK-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.9], class C) 319 // CHECK-NEXT: 9: return [B1.8]; 320 C returnChainOfCopies() { 321 return C(C::get()); 322 } 323 324 } // end namespace return_stmt_without_dtor 325 326 namespace return_stmt_with_dtor { 327 328 class D { 329 public: 330 D(); 331 ~D(); 332 }; 333 334 // CHECK: return_stmt_with_dtor::D returnTemporary() 335 // CHECK: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], class return_stmt_with_dtor::D) 336 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 337 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D) 338 // CHECK-NEXT: 4: [B1.3] 339 // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D) 340 // CHECK-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor) 341 // CHECK-NEXT: 7: return [B1.5]; 342 D returnTemporary() { 343 return D(); 344 } 345 346 } // end namespace return_stmt_with_dtor 347 348 namespace temporary_object_expr_without_dtors { 349 350 // TODO: Should provide construction context for the constructor, 351 // even if there is no specific trigger statement here. 352 // CHECK: void simpleTemporary() 353 // CHECK 1: C() (CXXConstructExpr, class C) 354 void simpleTemporary() { 355 C(); 356 } 357 358 // TODO: Should provide construction context for the constructor, 359 // CHECK: void temporaryInCondition() 360 // CHECK: 1: C() (CXXConstructExpr, class C) 361 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, NoOp, const class C) 362 // CHECK-NEXT: 3: [B2.2].operator bool 363 // CHECK-NEXT: 4: [B2.2] 364 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) 365 // CHECK-NEXT: T: if [B2.5] 366 void temporaryInCondition() { 367 if (C()); 368 } 369 370 } // end namespace temporary_object_expr_without_dtors 371 372 namespace temporary_object_expr_with_dtors { 373 374 class D { 375 public: 376 D(); 377 D(int); 378 ~D(); 379 380 static D get(); 381 382 operator bool() const; 383 }; 384 385 // CHECK: void simpleTemporary() 386 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D) 387 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 388 // CHECK-NEXT: 3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 389 void simpleTemporary() { 390 D(); 391 } 392 393 // CHECK: void temporaryInCondition() 394 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], class temporary_object_expr_with_dtors::D) 395 // CHECK-NEXT: 2: [B2.1] (BindTemporary) 396 // CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 397 // CHECK-NEXT: 4: [B2.3].operator bool 398 // CHECK-NEXT: 5: [B2.3] 399 // CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) 400 // CHECK-NEXT: 7: ~temporary_object_expr_with_dtors::D() (Temporary object destructor) 401 // CHECK-NEXT: T: if [B2.6] 402 void temporaryInCondition() { 403 if (D()); 404 } 405 406 // CHECK: void referenceVariableWithConstructor() 407 // CHECK: 1: 0 408 // CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], [B1.4], const class temporary_object_expr_with_dtors::D) 409 // CHECK-NEXT: 3: [B1.2] (BindTemporary) 410 // CHECK-NEXT: 4: [B1.3] 411 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0); 412 // CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor) 413 void referenceVariableWithConstructor() { 414 const D &d(0); 415 } 416 417 // CHECK: void referenceVariableWithInitializer() 418 // CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], [B1.4], class temporary_object_expr_with_dtors::D) 419 // CHECK-NEXT: 2: [B1.1] (BindTemporary) 420 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 421 // CHECK-NEXT: 4: [B1.3] 422 // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D(); 423 // CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor) 424 void referenceVariableWithInitializer() { 425 const D &d = D(); 426 } 427 428 // CHECK: void referenceVariableWithTernaryOperator(bool coin) 429 // CHECK: [B4] 430 // CHECK-NEXT: 1: [B7.2] ? [B5.8] : [B6.8] 431 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 432 // CHECK-NEXT: 3: [B4.2] 433 // CHECK-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0); 434 // CHECK-NEXT: T: (Temp Dtor) [B6.3] 435 // CHECK: [B5] 436 // CHECK-NEXT: 1: D::get 437 // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) 438 // CHECK-NEXT: 3: [B5.2]() 439 // CHECK-NEXT: 4: [B5.3] (BindTemporary) 440 // CHECK-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 441 // CHECK-NEXT: 6: [B5.5] 442 // CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], [B4.3], class temporary_object_expr_with_dtors::D) 443 // CHECK-NEXT: 8: [B5.7] (BindTemporary) 444 // CHECK: [B6] 445 // CHECK-NEXT: 1: 0 446 // CHECK-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], class temporary_object_expr_with_dtors::D) 447 // CHECK-NEXT: 3: [B6.2] (BindTemporary) 448 // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) 449 // CHECK-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 450 // CHECK-NEXT: 6: [B6.5] 451 // CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], [B4.3], class temporary_object_expr_with_dtors::D) 452 // CHECK-NEXT: 8: [B6.7] (BindTemporary) 453 // CHECK: [B7] 454 // CHECK-NEXT: 1: coin 455 // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) 456 // CHECK-NEXT: T: [B7.2] ? ... : ... 457 void referenceVariableWithTernaryOperator(bool coin) { 458 const D &d = coin ? D::get() : D(0); 459 } 460 461 // CHECK: void referenceWithFunctionalCast() 462 // CHECK: 1: 1 463 // CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], [B1.5], class temporary_object_expr_with_dtors::D) 464 // CHECK-NEXT: 3: [B1.2] (BindTemporary) 465 // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B1.3]) (CXXFunctionalCastExpr, ConstructorCon 466 // CHECK-NEXT: 5: [B1.4] 467 // CHECK-NEXT: 6: temporary_object_expr_with_dtors::D &&d = temporary_object_expr_with_dtors::D(1); 468 // CHECK-NEXT: 7: [B1.6].~D() (Implicit destructor) 469 void referenceWithFunctionalCast() { 470 D &&d = D(1); 471 } 472 473 // Test the condition constructor, we don't care about branch constructors here. 474 // CHECK: void constructorInTernaryCondition() 475 // CHECK: 1: 1 476 // CHECK-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], class temporary_object_expr_with_dtors::D) 477 // CHECK-NEXT: 3: [B7.2] (BindTemporary) 478 // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B7.3]) (CXXFunctionalCastExpr, ConstructorConv 479 // CHECK-NEXT: 5: [B7.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) 480 // CHECK-NEXT: 6: [B7.5].operator bool 481 // CHECK-NEXT: 7: [B7.5] 482 // CHECK-NEXT: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool) 483 // CHECK-NEXT: T: [B7.8] ? ... : ... 484 void constructorInTernaryCondition() { 485 const D &d = D(1) ? D(2) : D(3); 486 } 487 } // end namespace temporary_object_expr_with_dtors 488