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