blob: cad32f842c23e40d465eea7d5cafb935e93c2731 [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// 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]
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000119// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], class C)
Artem Dergachev08225bb2018-02-10 02:46:14 +0000120// CHECK: [B3]
121// CHECK-NEXT: 1: 0
122// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
Artem Dergachevceb7d912018-02-24 02:05:11 +0000123// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C)
Artem Dergachev08225bb2018-02-10 02:46:14 +0000124// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
125// CHECK-NEXT: 5: [B3.4]
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000126// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], class C)
Artem Dergachev08225bb2018-02-10 02:46:14 +0000127// CHECK: [B4]
128// CHECK-NEXT: 1: coin
129// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
130// CHECK-NEXT: T: [B4.2] ? ... : ...
131void simpleVariableWithTernaryOperator(bool coin) {
132 C c = coin ? C::get() : C(0);
133}
134
Artem Dergachevceb7d912018-02-24 02:05:11 +0000135// 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);
143void simpleVariableWithElidableCopy() {
144 C c = C(0);
145}
146
Artem Dergachev5fc10332018-02-10 01:55:23 +0000147// CHECK: void referenceVariableWithConstructor()
148// CHECK: 1: 0
149// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
Artem Dergachevf43ac4c2018-02-24 02:00:30 +0000150// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], const class C)
Artem Dergachev5fc10332018-02-10 01:55:23 +0000151// CHECK-NEXT: 4: [B1.3]
152// CHECK-NEXT: 5: const C &c(0);
153void referenceVariableWithConstructor() {
154 const C &c(0);
155}
156
Artem Dergachev5fc10332018-02-10 01:55:23 +0000157// CHECK: void referenceVariableWithInitializer()
Artem Dergachev8cc55e92018-02-24 02:07:50 +0000158// CHECK: 1: C() (CXXConstructExpr, [B1.3], class C)
Artem Dergachev5fc10332018-02-10 01:55:23 +0000159// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
160// CHECK-NEXT: 3: [B1.2]
161// CHECK-NEXT: 4: const C &c = C();
162void referenceVariableWithInitializer() {
163 const C &c = C();
164}
165
Artem Dergachev08225bb2018-02-10 02:46:14 +0000166// 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]
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000177// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.3], class C)
Artem Dergachev08225bb2018-02-10 02:46:14 +0000178// CHECK: [B3]
179// CHECK-NEXT: 1: 0
180// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
Artem Dergachevceb7d912018-02-24 02:05:11 +0000181// CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C)
Artem Dergachev08225bb2018-02-10 02:46:14 +0000182// CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
183// CHECK-NEXT: 5: [B3.4]
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000184// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.3], class C)
Artem Dergachev08225bb2018-02-10 02:46:14 +0000185// CHECK: [B4]
186// CHECK-NEXT: 1: coin
187// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
188// CHECK-NEXT: T: [B4.2] ? ... : ...
189void referenceVariableWithTernaryOperator(bool coin) {
190 const C &c = coin ? C::get() : C(0);
191}
192
Artem Dergachev5fc10332018-02-10 01:55:23 +0000193} // end namespace decl_stmt
Artem Dergachev5a281bb2018-02-10 02:18:04 +0000194
195namespace ctor_initializers {
196
197class D: public C {
198 C c1;
199
200public:
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() {}
Artem Dergachev08225bb2018-02-10 02:46:14 +0000216
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())) {}
Artem Dergachev5a281bb2018-02-10 02:18:04 +0000234};
235
236} // end namespace ctor_initializers
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000237
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000238namespace return_stmt_without_dtor {
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000239
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];
247C 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];
255C 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];
265C 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];
274C returnBracesWithMultipleItems() {
275 return {123, 456};
276}
277
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000278// CHECK: C returnTemporary()
Artem Dergachevf43ac4c2018-02-24 02:00:30 +0000279// CHECK: 1: C() (CXXConstructExpr, [B1.2], class C)
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000280// CHECK-NEXT: 2: [B1.1]
281// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], class C)
282// CHECK-NEXT: 4: return [B1.3];
283C returnTemporary() {
284 return C();
285}
286
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000287// CHECK: C returnTemporaryWithArgument()
288// CHECK: 1: nullptr
289// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
Artem Dergachevceb7d912018-02-24 02:05:11 +0000290// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C)
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000291// 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];
295C 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];
306C returnTemporaryConstructedByFunction() {
307 return C::get();
308}
309
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000310// 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]
Artem Dergachevceb7d912018-02-24 02:05:11 +0000315// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], class C)
Artem Dergachev9ac2e112018-02-12 22:36:36 +0000316// 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];
320C returnChainOfCopies() {
321 return C(C::get());
322}
323
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000324} // end namespace return_stmt_without_dtor
325
326namespace return_stmt_with_dtor {
327
328class D {
329public:
330 D();
331 ~D();
332};
333
334// CHECK: return_stmt_with_dtor::D returnTemporary()
Artem Dergachev8cc55e92018-02-24 02:07:50 +0000335// CHECK: 1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], class return_stmt_with_dtor::D)
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000336// 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];
342D returnTemporary() {
343 return D();
344}
345
346} // end namespace return_stmt_with_dtor
347
348namespace 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)
354void 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]
366void temporaryInCondition() {
367 if (C());
368}
369
370} // end namespace temporary_object_expr_without_dtors
371
372namespace temporary_object_expr_with_dtors {
373
374class D {
375public:
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)
389void 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]
402void temporaryInCondition() {
403 if (D());
404}
405
406// CHECK: void referenceVariableWithConstructor()
407// CHECK: 1: 0
Artem Dergachevf43ac4c2018-02-24 02:00:30 +0000408// 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 +0000409// 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)
413void referenceVariableWithConstructor() {
414 const D &d(0);
415}
416
417// CHECK: void referenceVariableWithInitializer()
Artem Dergachev8cc55e92018-02-24 02:07:50 +0000418// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], [B1.4], class temporary_object_expr_with_dtors::D)
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000419// 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)
424void 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]
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000442// CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], [B4.3], class temporary_object_expr_with_dtors::D)
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000443// CHECK-NEXT: 8: [B5.7] (BindTemporary)
444// CHECK: [B6]
445// CHECK-NEXT: 1: 0
Artem Dergachev8cc55e92018-02-24 02:07:50 +0000446// CHECK-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], class temporary_object_expr_with_dtors::D)
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000447// 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]
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000451// CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], [B4.3], class temporary_object_expr_with_dtors::D)
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000452// 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] ? ... : ...
457void referenceVariableWithTernaryOperator(bool coin) {
458 const D &d = coin ? D::get() : D(0);
459}
Artem Dergachevceb7d912018-02-24 02:05:11 +0000460
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)
469void referenceWithFunctionalCast() {
470 D &&d = D(1);
471}
Artem Dergacheva6d91d52018-02-24 03:10:15 +0000472
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] ? ... : ...
484void constructorInTernaryCondition() {
485 const D &d = D(1) ? D(2) : D(3);
486}
Artem Dergachev66030522018-03-01 01:09:24 +0000487
Artem Dergachev1f68d9d2018-02-15 03:13:36 +0000488} // end namespace temporary_object_expr_with_dtors
Artem Dergachev66030522018-03-01 01:09:24 +0000489
490namespace implicit_constructor_conversion {
491
492class A {};
493A get();
494
495class B {
496public:
497 B(const A &);
498 ~B() {}
499};
500
Artem Dergachev13f96642018-03-09 01:39:59 +0000501// CHECK: void implicitConstructionConversionFromTemporary()
502// CHECK: 1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A)
503// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
504// CHECK-NEXT: 3: [B1.2]
505// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], class implicit_constructor_conversion::B)
506// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
507// CHECK-NEXT: 6: [B1.5] (BindTemporary)
508// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
509// CHECK-NEXT: 8: [B1.7]
510// CHECK-NEXT: 9: [B1.8] (CXXConstructExpr, [B1.10], class implicit_constructor_conversion::B)
511// CHECK-NEXT: 10: implicit_constructor_conversion::B b = implicit_constructor_conversion::A();
512// CHECK-NEXT: 11: ~implicit_constructor_conversion::B() (Temporary object destructor)
513// CHECK-NEXT: 12: [B1.10].~B() (Implicit destructor)
514void implicitConstructionConversionFromTemporary() {
515 B b = A();
516}
517
Artem Dergachev66030522018-03-01 01:09:24 +0000518// CHECK: void implicitConstructionConversionFromFunctionValue()
519// CHECK: 1: get
Artem Dergachev13f96642018-03-09 01:39:59 +0000520// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conversion::A (*)(void))
521// CHECK-NEXT: 3: [B1.2]()
522// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
523// CHECK-NEXT: 5: [B1.4]
524// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], class implicit_constructor_conversion::B)
525// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
526// CHECK-NEXT: 8: [B1.7] (BindTemporary)
527// CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
528// CHECK-NEXT: 10: [B1.9]
529// CHECK-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], class implicit_constructor_conversion::B)
530// CHECK-NEXT: 12: implicit_constructor_conversion::B b = get();
531// CHECK-NEXT: 13: ~implicit_constructor_conversion::B() (Temporary object destructor)
532// CHECK-NEXT: 14: [B1.12].~B() (Implicit destructor)
533void implicitConstructionConversionFromFunctionValue() {
534 B b = get();
535}
536
537// CHECK: void implicitConstructionConversionFromTemporaryWithLifetimeExtension()
538// CHECK: 1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A)
539// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
540// CHECK-NEXT: 3: [B1.2]
541// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.7], class implicit_constructor_conversion::B)
542// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
543// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
544// CHECK-NEXT: 7: [B1.6]
545// CHECK-NEXT: 8: const implicit_constructor_conversion::B &b = implicit_constructor_conversion::A();
546// CHECK-NEXT: 9: [B1.8].~B() (Implicit destructor)
547void implicitConstructionConversionFromTemporaryWithLifetimeExtension() {
548 const B &b = A();
549}
550
551// FIXME: Find construction context for the implicit constructor conversion.
552// CHECK: void implicitConstructionConversionFromFunctionValueWithLifetimeExtension()
553// CHECK: 1: get
Artem Dergachev66030522018-03-01 01:09:24 +0000554// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver
555// CHECK-NEXT: 3: [B1.2]()
556// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
557// CHECK-NEXT: 5: [B1.4]
Artem Dergachev13f96642018-03-09 01:39:59 +0000558// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.9], class implicit_constructor_conversion::B)
Artem Dergachev66030522018-03-01 01:09:24 +0000559// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers
560// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
561// CHECK-NEXT: 9: [B1.8]
562// CHECK-NEXT: 10: const implicit_constructor_conversion::B &b = get();
563// CHECK-NEXT: 11: [B1.10].~B() (Implicit destructor)
Artem Dergachev13f96642018-03-09 01:39:59 +0000564void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() {
Artem Dergachev66030522018-03-01 01:09:24 +0000565 const B &b = get(); // no-crash
566}
567
568} // end namespace implicit_constructor_conversion