blob: 5dadb6cd819b0ae48a12501fd8a3e61576584d53 [file] [log] [blame]
Artem Dergachev1f68d9d2018-02-15 03:13:36 +00001// 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
Artem Dergachev41ffb302018-02-08 22:58:15 +00002// RUN: FileCheck --input-file=%t %s
3
4class C {
5public:
6 C();
7 C(C *);
Artem Dergachev9ac2e112018-02-12 22:36:36 +00008 C(int, int);
Artem Dergachev5fc10332018-02-10 01:55:23 +00009
10 static C get();
Artem Dergachev1f68d9d2018-02-15 03:13:36 +000011 operator bool() const;
Artem Dergachev41ffb302018-02-08 22:58:15 +000012};
13
14typedef __typeof(sizeof(int)) size_t;
15void *operator new(size_t size, void *placement);
16
17namespace 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])
23void 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])
34void 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])
46void operatorPlacementNewWithConstructorWithinPlacementArgument() {
47 new (new C()) C();
48}
49
50} // namespace operator_new
Artem Dergachev5fc10332018-02-10 01:55:23 +000051
52namespace decl_stmt {
53
54// CHECK: void simpleVariable()
55// CHECK: 1: (CXXConstructExpr, [B1.2], class C)
56// CHECK-NEXT: 2: C c;
57void simpleVariable() {
58 C c;
59}
60
61// CHECK: void simpleVariableWithBraces()
62// CHECK: 1: {} (CXXConstructExpr, [B1.2], class C)
63// CHECK-NEXT: 2: C c{};
64void 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);
73void 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());
83void 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()};
93void simpleVariableWithOperatorNewInBraces() {
94 C c{new C()};
95}
96
Artem Dergachev5fc10332018-02-10 01:55:23 +000097// 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]
Artem Dergachev08225bb2018-02-10 02:46:14 +0000102// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
Artem Dergachev5fc10332018-02-10 01:55:23 +0000103// CHECK-NEXT: 6: C c = C::get();
104void simpleVariableInitializedByValue() {
105 C c = C::get();
106}
107
Artem Dergachev08225bb2018-02-10 02:46:14 +0000108// TODO: Should find construction target for the three temporaries as well.
109// CHECK: void simpleVariableWithTernaryOperator(bool coin)
110// CHECK: [B1]
111// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
112// CHECK-NEXT: 2: [B1.1]
113// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C)
114// CHECK-NEXT: 4: C c = coin ? C::get() : C(0);
115// CHECK: [B2]
116// CHECK-NEXT: 1: C::get
117// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
118// CHECK-NEXT: 3: [B2.2]()
119// CHECK-NEXT: 4: [B2.3]
120// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
121// CHECK: [B3]
122// CHECK-NEXT: 1: 0
123// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
124// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
125// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
126// CHECK-NEXT: 5: [B3.4]
127// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
128// CHECK: [B4]
129// CHECK-NEXT: 1: coin
130// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
131// CHECK-NEXT: T: [B4.2] ? ... : ...
132void simpleVariableWithTernaryOperator(bool coin) {
133 C c = coin ? C::get() : C(0);
134}
135
Artem Dergachev5fc10332018-02-10 01:55:23 +0000136// CHECK: void referenceVariableWithConstructor()
137// CHECK: 1: 0
138// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
Artem Dergachevf43ac4c2018-02-24 02:00:30 +0000139// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], const class C)
Artem Dergachev5fc10332018-02-10 01:55:23 +0000140// CHECK-NEXT: 4: [B1.3]
141// CHECK-NEXT: 5: const C &c(0);
142void referenceVariableWithConstructor() {
143 const C &c(0);
144}
145
146// TODO: Should find construction target here.
147// CHECK: void referenceVariableWithInitializer()
148// CHECK: 1: C() (CXXConstructExpr, class C)
149// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
150// CHECK-NEXT: 3: [B1.2]
151// CHECK-NEXT: 4: const C &c = C();
152void referenceVariableWithInitializer() {
153 const C &c = C();
154}
155
Artem Dergachev08225bb2018-02-10 02:46:14 +0000156// TODO: Should find construction targets here.
157// CHECK: void referenceVariableWithTernaryOperator(bool coin)
158// CHECK: [B1]
159// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
160// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
161// CHECK-NEXT: 3: [B1.2]
162// CHECK-NEXT: 4: const C &c = coin ? C::get() : C(0);
163// CHECK: [B2]
164// CHECK-NEXT: 1: C::get
165// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
166// CHECK-NEXT: 3: [B2.2]()
167// CHECK-NEXT: 4: [B2.3]
168// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
169// CHECK: [B3]
170// CHECK-NEXT: 1: 0
171// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
172// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
173// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
174// CHECK-NEXT: 5: [B3.4]
175// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
176// CHECK: [B4]
177// CHECK-NEXT: 1: coin
178// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
179// CHECK-NEXT: T: [B4.2] ? ... : ...
180void referenceVariableWithTernaryOperator(bool coin) {
181 const C &c = coin ? C::get() : C(0);
182}
183
Artem Dergachev5fc10332018-02-10 01:55:23 +0000184} // end namespace decl_stmt
Artem Dergachev5a281bb2018-02-10 02:18:04 +0000185
186namespace ctor_initializers {
187
188class D: public C {
189 C c1;
190
191public:
192
193// CHECK: D()
194// CHECK: 1: (CXXConstructExpr, C() (Base initializer), class C)
195// CHECK-NEXT: 2: C([B1.1]) (Base initializer)
196// CHECK-NEXT: 3: CFGNewAllocator(C *)
197// CHECK-NEXT: 4: (CXXConstructExpr, [B1.5], class C)
198// CHECK-NEXT: 5: new C([B1.4])
199// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, c1([B1.5]) (Member initializer), class C)
200// CHECK-NEXT: 7: c1([B1.6]) (Member initializer)
201 D(): C(), c1(new C()) {}
202
203// CHECK: D(int)
204// CHECK: 1: (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D)
205// CHECK-NEXT: 2: D([B1.1]) (Delegating initializer)
206 D(int): D() {}
Artem Dergachev08225bb2018-02-10 02:46:14 +0000207
208// CHECK: D(double)
209// CHECK: 1: C::get
210// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
211// CHECK-NEXT: 3: [B1.2]()
212// CHECK-NEXT: 4: [B1.3]
213// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), class C)
214// CHECK-NEXT: 6: C([B1.5]) (Base initializer)
215// CHECK-NEXT: 7: CFGNewAllocator(C *)
216// CHECK-NEXT: 8: C::get
217// CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
218// CHECK-NEXT: 10: [B1.9]()
219// CHECK-NEXT: 11: [B1.10]
220// CHECK-NEXT: 12: [B1.11] (CXXConstructExpr, [B1.13], class C)
221// CHECK-NEXT: 13: new C([B1.12])
222// CHECK-NEXT: 14: [B1.13] (CXXConstructExpr, c1([B1.13]) (Member initializer), class C)
223// CHECK-NEXT: 15: c1([B1.14]) (Member initializer)
224 D(double): C(C::get()), c1(new C(C::get())) {}
Artem Dergachev5a281bb2018-02-10 02:18:04 +0000225};
226
227} // end namespace ctor_initializers
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000228
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000229namespace return_stmt_without_dtor {
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000230
231// CHECK: C returnVariable()
232// CHECK: 1: (CXXConstructExpr, [B1.2], class C)
233// CHECK-NEXT: 2: C c;
234// CHECK-NEXT: 3: c
235// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, class C)
236// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
237// CHECK-NEXT: 6: return [B1.5];
238C returnVariable() {
239 C c;
240 return c;
241}
242
243// CHECK: C returnEmptyBraces()
244// CHECK: 1: {} (CXXConstructExpr, [B1.2], class C)
245// CHECK-NEXT: 2: return [B1.1];
246C returnEmptyBraces() {
247 return {};
248}
249
250// CHECK: C returnBracesWithOperatorNew()
251// CHECK: 1: CFGNewAllocator(C *)
252// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C)
253// CHECK-NEXT: 3: new C([B1.2])
254// CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], class C)
255// CHECK-NEXT: 5: return [B1.4];
256C returnBracesWithOperatorNew() {
257 return {new C()};
258}
259
260// CHECK: C returnBracesWithMultipleItems()
261// CHECK: 1: 123
262// CHECK-NEXT: 2: 456
263// CHECK-NEXT: 3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], class C)
264// CHECK-NEXT: 4: return [B1.3];
265C returnBracesWithMultipleItems() {
266 return {123, 456};
267}
268
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000269// CHECK: C returnTemporary()
Artem Dergachevf43ac4c2018-02-24 02:00:30 +0000270// CHECK: 1: C() (CXXConstructExpr, [B1.2], class C)
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000271// CHECK-NEXT: 2: [B1.1]
272// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C)
273// CHECK-NEXT: 4: return [B1.3];
274C returnTemporary() {
275 return C();
276}
277
278// TODO: Should find construction targets for the first constructor as well.
279// CHECK: C returnTemporaryWithArgument()
280// CHECK: 1: nullptr
281// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
282// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, class C)
283// CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
284// CHECK-NEXT: 5: [B1.4]
285// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], class C)
286// CHECK-NEXT: 7: return [B1.6];
287C returnTemporaryWithArgument() {
288 return C(nullptr);
289}
290
291// CHECK: C returnTemporaryConstructedByFunction()
292// CHECK: 1: C::get
293// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
294// CHECK-NEXT: 3: [B1.2]()
295// CHECK-NEXT: 4: [B1.3]
296// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
297// CHECK-NEXT: 6: return [B1.5];
298C returnTemporaryConstructedByFunction() {
299 return C::get();
300}
301
302// TODO: Should find construction targets for the first constructor as well.
303// CHECK: C returnChainOfCopies()
304// CHECK: 1: C::get
305// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
306// CHECK-NEXT: 3: [B1.2]()
307// CHECK-NEXT: 4: [B1.3]
308// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, class C)
309// CHECK-NEXT: 6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
310// CHECK-NEXT: 7: [B1.6]
311// CHECK-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.9], class C)
312// CHECK-NEXT: 9: return [B1.8];
313C returnChainOfCopies() {
314 return C(C::get());
315}
316
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000317} // end namespace return_stmt_without_dtor
318
319namespace return_stmt_with_dtor {
320
321class D {
322public:
323 D();
324 ~D();
325};
326
327// CHECK: return_stmt_with_dtor::D returnTemporary()
328// CHECK: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], class return_stmt_with_dtor::D)
329// CHECK-NEXT: 2: [B1.1] (BindTemporary)
330// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D)
331// CHECK-NEXT: 4: [B1.3]
332// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D)
333// CHECK-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor)
334// CHECK-NEXT: 7: return [B1.5];
335D returnTemporary() {
336 return D();
337}
338
339} // end namespace return_stmt_with_dtor
340
341namespace temporary_object_expr_without_dtors {
342
343// TODO: Should provide construction context for the constructor,
344// even if there is no specific trigger statement here.
345// CHECK: void simpleTemporary()
346// CHECK 1: C() (CXXConstructExpr, class C)
347void simpleTemporary() {
348 C();
349}
350
351// TODO: Should provide construction context for the constructor,
352// CHECK: void temporaryInCondition()
353// CHECK: 1: C() (CXXConstructExpr, class C)
354// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, NoOp, const class C)
355// CHECK-NEXT: 3: [B2.2].operator bool
356// CHECK-NEXT: 4: [B2.2]
357// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
358// CHECK-NEXT: T: if [B2.5]
359void temporaryInCondition() {
360 if (C());
361}
362
363} // end namespace temporary_object_expr_without_dtors
364
365namespace temporary_object_expr_with_dtors {
366
367class D {
368public:
369 D();
370 D(int);
371 ~D();
372
373 static D get();
374
375 operator bool() const;
376};
377
378// CHECK: void simpleTemporary()
379// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D)
380// CHECK-NEXT: 2: [B1.1] (BindTemporary)
381// CHECK-NEXT: 3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
382void simpleTemporary() {
383 D();
384}
385
386// CHECK: void temporaryInCondition()
387// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], class temporary_object_expr_with_dtors::D)
388// CHECK-NEXT: 2: [B2.1] (BindTemporary)
389// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
390// CHECK-NEXT: 4: [B2.3].operator bool
391// CHECK-NEXT: 5: [B2.3]
392// CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
393// CHECK-NEXT: 7: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
394// CHECK-NEXT: T: if [B2.6]
395void temporaryInCondition() {
396 if (D());
397}
398
399// CHECK: void referenceVariableWithConstructor()
400// CHECK: 1: 0
Artem Dergachevf43ac4c2018-02-24 02:00:30 +0000401// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], [B1.4], const class temporary_object_expr_with_dtors::D)
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000402// CHECK-NEXT: 3: [B1.2] (BindTemporary)
403// CHECK-NEXT: 4: [B1.3]
404// CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0);
405// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor)
406void referenceVariableWithConstructor() {
407 const D &d(0);
408}
409
410// CHECK: void referenceVariableWithInitializer()
411// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D)
412// CHECK-NEXT: 2: [B1.1] (BindTemporary)
413// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
414// CHECK-NEXT: 4: [B1.3]
415// CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D();
416// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor)
417void referenceVariableWithInitializer() {
418 const D &d = D();
419}
420
421// CHECK: void referenceVariableWithTernaryOperator(bool coin)
422// CHECK: [B4]
423// CHECK-NEXT: 1: [B7.2] ? [B5.8] : [B6.8]
424// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
425// CHECK-NEXT: 3: [B4.2]
426// CHECK-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0);
427// CHECK-NEXT: T: (Temp Dtor) [B6.3]
428// CHECK: [B5]
429// CHECK-NEXT: 1: D::get
430// CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void))
431// CHECK-NEXT: 3: [B5.2]()
432// CHECK-NEXT: 4: [B5.3] (BindTemporary)
433// CHECK-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
434// CHECK-NEXT: 6: [B5.5]
435// CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], class temporary_object_expr_with_dtors::D)
436// CHECK-NEXT: 8: [B5.7] (BindTemporary)
437// CHECK: [B6]
438// CHECK-NEXT: 1: 0
439// CHECK-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], class temporary_object_expr_with_dtors::D)
440// CHECK-NEXT: 3: [B6.2] (BindTemporary)
441// CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
442// CHECK-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
443// CHECK-NEXT: 6: [B6.5]
444// CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], class temporary_object_expr_with_dtors::D)
445// CHECK-NEXT: 8: [B6.7] (BindTemporary)
446// CHECK: [B7]
447// CHECK-NEXT: 1: coin
448// CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
449// CHECK-NEXT: T: [B7.2] ? ... : ...
450void referenceVariableWithTernaryOperator(bool coin) {
451 const D &d = coin ? D::get() : D(0);
452}
453} // end namespace temporary_object_expr_with_dtors