blob: 5818912d267a323748805b78ef8af03dc3a528ce [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// TODO: Should find construction target here.
137// CHECK: void referenceVariableWithConstructor()
138// CHECK: 1: 0
139// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
140// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, const class C)
141// CHECK-NEXT: 4: [B1.3]
142// CHECK-NEXT: 5: const C &c(0);
143void referenceVariableWithConstructor() {
144 const C &c(0);
145}
146
147// TODO: Should find construction target here.
148// CHECK: void referenceVariableWithInitializer()
149// CHECK: 1: C() (CXXConstructExpr, class C)
150// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
151// CHECK-NEXT: 3: [B1.2]
152// CHECK-NEXT: 4: const C &c = C();
153void referenceVariableWithInitializer() {
154 const C &c = C();
155}
156
Artem Dergachev08225bb2018-02-10 02:46:14 +0000157// TODO: Should find construction targets here.
158// CHECK: void referenceVariableWithTernaryOperator(bool coin)
159// CHECK: [B1]
160// CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]
161// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
162// CHECK-NEXT: 3: [B1.2]
163// CHECK-NEXT: 4: const C &c = coin ? C::get() : C(0);
164// CHECK: [B2]
165// CHECK-NEXT: 1: C::get
166// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
167// CHECK-NEXT: 3: [B2.2]()
168// CHECK-NEXT: 4: [B2.3]
169// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C)
170// CHECK: [B3]
171// CHECK-NEXT: 1: 0
172// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
173// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, class C)
174// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
175// CHECK-NEXT: 5: [B3.4]
176// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C)
177// CHECK: [B4]
178// CHECK-NEXT: 1: coin
179// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
180// CHECK-NEXT: T: [B4.2] ? ... : ...
181void referenceVariableWithTernaryOperator(bool coin) {
182 const C &c = coin ? C::get() : C(0);
183}
184
Artem Dergachev5fc10332018-02-10 01:55:23 +0000185} // end namespace decl_stmt
Artem Dergachev5a281bb2018-02-10 02:18:04 +0000186
187namespace ctor_initializers {
188
189class D: public C {
190 C c1;
191
192public:
193
194// CHECK: D()
195// CHECK: 1: (CXXConstructExpr, C() (Base initializer), class C)
196// CHECK-NEXT: 2: C([B1.1]) (Base initializer)
197// CHECK-NEXT: 3: CFGNewAllocator(C *)
198// CHECK-NEXT: 4: (CXXConstructExpr, [B1.5], class C)
199// CHECK-NEXT: 5: new C([B1.4])
200// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, c1([B1.5]) (Member initializer), class C)
201// CHECK-NEXT: 7: c1([B1.6]) (Member initializer)
202 D(): C(), c1(new C()) {}
203
204// CHECK: D(int)
205// CHECK: 1: (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D)
206// CHECK-NEXT: 2: D([B1.1]) (Delegating initializer)
207 D(int): D() {}
Artem Dergachev08225bb2018-02-10 02:46:14 +0000208
209// CHECK: D(double)
210// CHECK: 1: C::get
211// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
212// CHECK-NEXT: 3: [B1.2]()
213// CHECK-NEXT: 4: [B1.3]
214// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), class C)
215// CHECK-NEXT: 6: C([B1.5]) (Base initializer)
216// CHECK-NEXT: 7: CFGNewAllocator(C *)
217// CHECK-NEXT: 8: C::get
218// CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
219// CHECK-NEXT: 10: [B1.9]()
220// CHECK-NEXT: 11: [B1.10]
221// CHECK-NEXT: 12: [B1.11] (CXXConstructExpr, [B1.13], class C)
222// CHECK-NEXT: 13: new C([B1.12])
223// CHECK-NEXT: 14: [B1.13] (CXXConstructExpr, c1([B1.13]) (Member initializer), class C)
224// CHECK-NEXT: 15: c1([B1.14]) (Member initializer)
225 D(double): C(C::get()), c1(new C(C::get())) {}
Artem Dergachev5a281bb2018-02-10 02:18:04 +0000226};
227
228} // end namespace ctor_initializers
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000229
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000230namespace return_stmt_without_dtor {
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000231
232// CHECK: C returnVariable()
233// CHECK: 1: (CXXConstructExpr, [B1.2], class C)
234// CHECK-NEXT: 2: C c;
235// CHECK-NEXT: 3: c
236// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, class C)
237// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
238// CHECK-NEXT: 6: return [B1.5];
239C returnVariable() {
240 C c;
241 return c;
242}
243
244// CHECK: C returnEmptyBraces()
245// CHECK: 1: {} (CXXConstructExpr, [B1.2], class C)
246// CHECK-NEXT: 2: return [B1.1];
247C returnEmptyBraces() {
248 return {};
249}
250
251// CHECK: C returnBracesWithOperatorNew()
252// CHECK: 1: CFGNewAllocator(C *)
253// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], class C)
254// CHECK-NEXT: 3: new C([B1.2])
255// CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], class C)
256// CHECK-NEXT: 5: return [B1.4];
257C returnBracesWithOperatorNew() {
258 return {new C()};
259}
260
261// CHECK: C returnBracesWithMultipleItems()
262// CHECK: 1: 123
263// CHECK-NEXT: 2: 456
264// CHECK-NEXT: 3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], class C)
265// CHECK-NEXT: 4: return [B1.3];
266C returnBracesWithMultipleItems() {
267 return {123, 456};
268}
269
270// TODO: Should find construction targets for the first constructor as well.
271// CHECK: C returnTemporary()
272// CHECK: 1: C() (CXXConstructExpr, class C)
273// CHECK-NEXT: 2: [B1.1]
274// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C)
275// CHECK-NEXT: 4: return [B1.3];
276C returnTemporary() {
277 return C();
278}
279
280// TODO: Should find construction targets for the first constructor as well.
281// CHECK: C returnTemporaryWithArgument()
282// CHECK: 1: nullptr
283// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
284// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, class C)
285// CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
286// CHECK-NEXT: 5: [B1.4]
287// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], class C)
288// CHECK-NEXT: 7: return [B1.6];
289C returnTemporaryWithArgument() {
290 return C(nullptr);
291}
292
293// CHECK: C returnTemporaryConstructedByFunction()
294// CHECK: 1: C::get
295// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
296// CHECK-NEXT: 3: [B1.2]()
297// CHECK-NEXT: 4: [B1.3]
298// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], class C)
299// CHECK-NEXT: 6: return [B1.5];
300C returnTemporaryConstructedByFunction() {
301 return C::get();
302}
303
304// TODO: Should find construction targets for the first constructor as well.
305// CHECK: C returnChainOfCopies()
306// CHECK: 1: C::get
307// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
308// CHECK-NEXT: 3: [B1.2]()
309// CHECK-NEXT: 4: [B1.3]
310// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, class C)
311// CHECK-NEXT: 6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
312// CHECK-NEXT: 7: [B1.6]
313// CHECK-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.9], class C)
314// CHECK-NEXT: 9: return [B1.8];
315C returnChainOfCopies() {
316 return C(C::get());
317}
318
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000319} // end namespace return_stmt_without_dtor
320
321namespace return_stmt_with_dtor {
322
323class D {
324public:
325 D();
326 ~D();
327};
328
329// CHECK: return_stmt_with_dtor::D returnTemporary()
330// CHECK: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], class return_stmt_with_dtor::D)
331// CHECK-NEXT: 2: [B1.1] (BindTemporary)
332// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D)
333// CHECK-NEXT: 4: [B1.3]
334// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D)
335// CHECK-NEXT: 6: ~return_stmt_with_dtor::D() (Temporary object destructor)
336// CHECK-NEXT: 7: return [B1.5];
337D returnTemporary() {
338 return D();
339}
340
341} // end namespace return_stmt_with_dtor
342
343namespace temporary_object_expr_without_dtors {
344
345// TODO: Should provide construction context for the constructor,
346// even if there is no specific trigger statement here.
347// CHECK: void simpleTemporary()
348// CHECK 1: C() (CXXConstructExpr, class C)
349void simpleTemporary() {
350 C();
351}
352
353// TODO: Should provide construction context for the constructor,
354// CHECK: void temporaryInCondition()
355// CHECK: 1: C() (CXXConstructExpr, class C)
356// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, NoOp, const class C)
357// CHECK-NEXT: 3: [B2.2].operator bool
358// CHECK-NEXT: 4: [B2.2]
359// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
360// CHECK-NEXT: T: if [B2.5]
361void temporaryInCondition() {
362 if (C());
363}
364
365} // end namespace temporary_object_expr_without_dtors
366
367namespace temporary_object_expr_with_dtors {
368
369class D {
370public:
371 D();
372 D(int);
373 ~D();
374
375 static D get();
376
377 operator bool() const;
378};
379
380// CHECK: void simpleTemporary()
381// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D)
382// CHECK-NEXT: 2: [B1.1] (BindTemporary)
383// CHECK-NEXT: 3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
384void simpleTemporary() {
385 D();
386}
387
388// CHECK: void temporaryInCondition()
389// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], class temporary_object_expr_with_dtors::D)
390// CHECK-NEXT: 2: [B2.1] (BindTemporary)
391// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
392// CHECK-NEXT: 4: [B2.3].operator bool
393// CHECK-NEXT: 5: [B2.3]
394// CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
395// CHECK-NEXT: 7: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
396// CHECK-NEXT: T: if [B2.6]
397void temporaryInCondition() {
398 if (D());
399}
400
401// CHECK: void referenceVariableWithConstructor()
402// CHECK: 1: 0
403// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], const class temporary_object_expr_with_dtors::D)
404// CHECK-NEXT: 3: [B1.2] (BindTemporary)
405// CHECK-NEXT: 4: [B1.3]
406// CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0);
407// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor)
408void referenceVariableWithConstructor() {
409 const D &d(0);
410}
411
412// CHECK: void referenceVariableWithInitializer()
413// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D)
414// CHECK-NEXT: 2: [B1.1] (BindTemporary)
415// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
416// CHECK-NEXT: 4: [B1.3]
417// CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D();
418// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor)
419void referenceVariableWithInitializer() {
420 const D &d = D();
421}
422
423// CHECK: void referenceVariableWithTernaryOperator(bool coin)
424// CHECK: [B4]
425// CHECK-NEXT: 1: [B7.2] ? [B5.8] : [B6.8]
426// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
427// CHECK-NEXT: 3: [B4.2]
428// CHECK-NEXT: 4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0);
429// CHECK-NEXT: T: (Temp Dtor) [B6.3]
430// CHECK: [B5]
431// CHECK-NEXT: 1: D::get
432// CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void))
433// CHECK-NEXT: 3: [B5.2]()
434// CHECK-NEXT: 4: [B5.3] (BindTemporary)
435// CHECK-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
436// CHECK-NEXT: 6: [B5.5]
437// CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], class temporary_object_expr_with_dtors::D)
438// CHECK-NEXT: 8: [B5.7] (BindTemporary)
439// CHECK: [B6]
440// CHECK-NEXT: 1: 0
441// CHECK-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], class temporary_object_expr_with_dtors::D)
442// CHECK-NEXT: 3: [B6.2] (BindTemporary)
443// CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
444// CHECK-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
445// CHECK-NEXT: 6: [B6.5]
446// CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], class temporary_object_expr_with_dtors::D)
447// CHECK-NEXT: 8: [B6.7] (BindTemporary)
448// CHECK: [B7]
449// CHECK-NEXT: 1: coin
450// CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
451// CHECK-NEXT: T: [B7.2] ? ... : ...
452void referenceVariableWithTernaryOperator(bool coin) {
453 const D &d = coin ? D::get() : D(0);
454}
455} // end namespace temporary_object_expr_with_dtors