Clang Project

clang_source_code/test/Analysis/cfg-rich-constructors.cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w %s > %t 2>&1
2// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,ELIDE,CXX11-ELIDE %s
3// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w %s > %t 2>&1
4// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17,ELIDE,CXX17-ELIDE %s
5// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w -analyzer-config elide-constructors=false %s > %t 2>&1
6// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,NOELIDE,CXX11-NOELIDE %s
7// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w -analyzer-config elide-constructors=false %s > %t 2>&1
8// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17,NOELIDE,CXX17-NOELIDE %s
9
10class C {
11public:
12  C();
13  C(C *);
14  C(int, int);
15
16  static C get();
17  operator bool() const;
18};
19
20typedef __typeof(sizeof(int)) size_t;
21void *operator new(size_t size, void *placement);
22
23namespace operator_new {
24
25// CHECK: void operatorNewWithConstructor()
26// CHECK:          1: CFGNewAllocator(C *)
27// CHECK-NEXT:     2:  (CXXConstructExpr, [B1.3], class C)
28// CHECK-NEXT:     3: new C([B1.2])
29void operatorNewWithConstructor() {
30  new C();
31}
32
33// CHECK: void operatorNewWithConstructorWithOperatorNewWithContstructor()
34// CHECK:          1: CFGNewAllocator(C *)
35// CHECK-NEXT:     2: CFGNewAllocator(C *)
36// CHECK-NEXT:     3:  (CXXConstructExpr, [B1.4], class C)
37// CHECK-NEXT:     4: new C([B1.3])
38// CHECK-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], class C)
39// CHECK-NEXT:     6: new C([B1.5])
40void operatorNewWithConstructorWithOperatorNewWithContstructor() {
41 new C(new C());
42}
43
44// CHECK: void operatorPlacementNewWithConstructorWithinPlacementArgument()
45// CHECK:          1: CFGNewAllocator(C *)
46// CHECK-NEXT:     2:  (CXXConstructExpr, [B1.3], class C)
47// CHECK-NEXT:     3: new C([B1.2])
48// CHECK-NEXT:     4: [B1.3] (ImplicitCastExpr, BitCast, void *)
49// CHECK-NEXT:     5: CFGNewAllocator(C *)
50// CHECK-NEXT:     6:  (CXXConstructExpr, [B1.7], class C)
51// CHECK-NEXT:     7: new ([B1.4]) C([B1.6])
52void operatorPlacementNewWithConstructorWithinPlacementArgument() {
53 new (new C()) C();
54}
55
56} // namespace operator_new
57
58namespace decl_stmt {
59
60// CHECK: void simpleVariable()
61// CHECK:          1:  (CXXConstructExpr, [B1.2], class C)
62// CHECK-NEXT:     2: C c;
63void simpleVariable() {
64  C c;
65}
66
67// CHECK: void simpleVariableWithBraces()
68// CHECK:          1: {} (CXXConstructExpr, [B1.2], class C)
69// CHECK-NEXT:     2: C c{};
70void simpleVariableWithBraces() {
71  C c{};
72}
73
74// CHECK: void simpleVariableWithConstructorArgument()
75// CHECK:          1: 0
76// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
77// CHECK-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.4], class C)
78// CHECK-NEXT:     4: C c(0);
79void simpleVariableWithConstructorArgument() {
80  C c(0);
81}
82
83// CHECK: void simpleVariableWithOperatorNewInConstructorArgument()
84// CHECK:          1: CFGNewAllocator(C *)
85// CHECK-NEXT:     2:  (CXXConstructExpr, [B1.3], class C)
86// CHECK-NEXT:     3: new C([B1.2])
87// CHECK-NEXT:     4: [B1.3] (CXXConstructExpr, [B1.5], class C)
88// CHECK-NEXT:     5: C c(new C());
89void simpleVariableWithOperatorNewInConstructorArgument() {
90  C c(new C());
91}
92
93// CHECK: void simpleVariableWithOperatorNewInBraces()
94// CHECK:          1: CFGNewAllocator(C *)
95// CHECK-NEXT:     2:  (CXXConstructExpr, [B1.3], class C)
96// CHECK-NEXT:     3: new C([B1.2])
97// CHECK-NEXT:     4: {[B1.3]} (CXXConstructExpr, [B1.5], class C)
98// CHECK-NEXT:     5: C c{new C()};
99void simpleVariableWithOperatorNewInBraces() {
100  C c{new C()};
101}
102
103// CHECK: void simpleVariableInitializedByValue()
104// CHECK:          1: C::get
105// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
106// CXX11-ELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])
107// CXX11-NOELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
108// CXX11-NEXT:     4: [B1.3]
109// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], class C)
110// CXX11-NEXT:     6: C c = C::get();
111// CXX17-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
112// CXX17-NEXT:     4: C c = C::get();
113void simpleVariableInitializedByValue() {
114  C c = C::get();
115}
116
117// FIXME: Find construction contexts for both branches in C++17.
118// Note that once it gets detected, the test for the get() branch would not
119// fail, because FileCheck allows partial matches.
120// CHECK: void simpleVariableWithTernaryOperator(bool coin)
121// CHECK:        [B1]
122// CXX11-NEXT:     1: [B4.2] ? [B2.5] : [B3.6]
123// CXX11-NEXT:     2: [B1.1]
124// CXX11-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.4], class C)
125// CXX11-NEXT:     4: C c = coin ? C::get() : C(0);
126// CXX17-NEXT:     1: [B4.2] ? [B2.3] : [B3.4]
127// CXX17-NEXT:     2: C c = coin ? C::get() : C(0);
128// CHECK:        [B2]
129// CHECK-NEXT:     1: C::get
130// CHECK-NEXT:     2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
131// CXX11-ELIDE-NEXT:     3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B2.5])
132// CXX11-NOELIDE-NEXT:     3: [B2.2]() (CXXRecordTypedCall, [B2.4])
133// CXX11-NEXT:     4: [B2.3]
134// CXX11-ELIDE-NEXT:     5: [B2.4] (CXXConstructExpr, [B1.2], [B1.3], class C)
135// CXX11-NOELIDE-NEXT:     5: [B2.4] (CXXConstructExpr, [B1.2], class C)
136// CXX17-NEXT:     3: [B2.2]()
137// CHECK:        [B3]
138// CHECK-NEXT:     1: 0
139// CHECK-NEXT:     2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
140// CXX11-ELIDE-NEXT:     3: [B3.2] (CXXConstructExpr, [B3.5], [B3.6], class C)
141// CXX11-NOELIDE-NEXT:     3: [B3.2] (CXXConstructExpr, [B3.5], class C)
142// CXX11-NEXT:     4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
143// CXX11-NEXT:     5: [B3.4]
144// CXX11-ELIDE-NEXT:     6: [B3.5] (CXXConstructExpr, [B1.2], [B1.3], class C)
145// CXX11-NOELIDE-NEXT:     6: [B3.5] (CXXConstructExpr, [B1.2], class C)
146// CXX17-NEXT:     3: [B3.2] (CXXConstructExpr, class C)
147// CXX17-NEXT:     4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
148// CHECK:        [B4]
149// CHECK-NEXT:     1: coin
150// CHECK-NEXT:     2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
151// CHECK-NEXT:     T: [B4.2] ? ... : ...
152void simpleVariableWithTernaryOperator(bool coin) {
153  C c = coin ? C::get() : C(0);
154}
155
156// CHECK: void simpleVariableWithElidableCopy()
157// CHECK:          1: 0
158// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
159// CXX11-ELIDE-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.5], [B1.6], class C)
160// CXX11-NOELIDE-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.5], class C)
161// CXX17-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.5], class C)
162// CHECK-NEXT:     4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
163// CXX11-NEXT:     5: [B1.4]
164// CXX11-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.7], class C)
165// CXX11-NEXT:     7: C c = C(0);
166// CXX17-NEXT:     5: C c = C(0);
167void simpleVariableWithElidableCopy() {
168  C c = C(0);
169}
170
171// CHECK: void referenceVariableWithConstructor()
172// CHECK:          1: 0
173// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
174// CHECK-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.4], const class C)
175// CHECK-NEXT:     4: [B1.3]
176// CHECK-NEXT:     5: const C &c(0);
177void referenceVariableWithConstructor() {
178  const C &c(0);
179}
180
181// CHECK: void referenceVariableWithInitializer()
182// CHECK:          1: C() (CXXConstructExpr, [B1.3], class C)
183// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
184// CHECK-NEXT:     3: [B1.2]
185// CHECK-NEXT:     4: const C &c = C();
186void referenceVariableWithInitializer() {
187  const C &c = C();
188}
189
190// CHECK: void referenceVariableWithTernaryOperator(bool coin)
191// CHECK:        [B1]
192// CXX11-NEXT:     1: [B4.2] ? [B2.5] : [B3.6]
193// CXX17-NEXT:     1: [B4.2] ? [B2.3] : [B3.4]
194// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class C)
195// CHECK-NEXT:     3: [B1.2]
196// CHECK-NEXT:     4: const C &c = coin ? C::get() : C(0);
197// CHECK:        [B2]
198// CHECK-NEXT:     1: C::get
199// CHECK-NEXT:     2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
200// CXX11-ELIDE-NEXT:     3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B2.5])
201// CXX11-NOELIDE-NEXT:     3: [B2.2]() (CXXRecordTypedCall, [B2.4])
202// CXX11-NEXT:     4: [B2.3]
203// CXX11-NEXT:     5: [B2.4] (CXXConstructExpr, [B1.3], class C)
204// CXX17-NEXT:     3: [B2.2]() (CXXRecordTypedCall, [B1.3])
205// CHECK:        [B3]
206// CHECK-NEXT:     1: 0
207// CHECK-NEXT:     2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *)
208// CXX11-ELIDE-NEXT:     3: [B3.2] (CXXConstructExpr, [B3.5], [B3.6], class C)
209// CXX11-NOELIDE-NEXT:     3: [B3.2] (CXXConstructExpr, [B3.5], class C)
210// CXX11-NEXT:     4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
211// CXX11-NEXT:     5: [B3.4]
212// CXX11-NEXT:     6: [B3.5] (CXXConstructExpr, [B1.3], class C)
213// CXX17-NEXT:     3: [B3.2] (CXXConstructExpr, [B1.3], class C)
214// CXX17-NEXT:     4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
215// CHECK:        [B4]
216// CHECK-NEXT:     1: coin
217// CHECK-NEXT:     2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
218// CHECK-NEXT:     T: [B4.2] ? ... : ...
219void referenceVariableWithTernaryOperator(bool coin) {
220  const C &c = coin ? C::get() : C(0);
221}
222
223} // end namespace decl_stmt
224
225namespace ctor_initializers {
226
227class D: public C {
228  C c1;
229
230public:
231
232// CHECK: D()
233// CHECK:          1:  (CXXConstructExpr, C() (Base initializer), class C)
234// CHECK-NEXT:     2: C([B1.1]) (Base initializer)
235// CHECK-NEXT:     3: CFGNewAllocator(C *)
236// CHECK-NEXT:     4:  (CXXConstructExpr, [B1.5], class C)
237// CHECK-NEXT:     5: new C([B1.4])
238// CHECK-NEXT:     6: [B1.5] (CXXConstructExpr, c1([B1.5]) (Member initializer), class C)
239// CHECK-NEXT:     7: c1([B1.6]) (Member initializer)
240  D(): C(), c1(new C()) {}
241
242// CHECK: D(int)
243// CHECK:          1:  (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D)
244// CHECK-NEXT:     2: D([B1.1]) (Delegating initializer)
245  D(int): D() {}
246
247// FIXME: Why is CXXRecordTypedCall not present in C++17? Note that once it gets
248// detected the test would not fail, because FileCheck allows partial matches.
249// CHECK: D(double)
250// CHECK:          1: C::get
251// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
252// CHECK-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
253// CHECK-NEXT:     4: [B1.3]
254// CHECK-NEXT:     5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), class C)
255// CHECK-NEXT:     6: C([B1.5]) (Base initializer)
256// CHECK-NEXT:     7: CFGNewAllocator(C *)
257// CHECK-NEXT:     8: C::get
258// CHECK-NEXT:     9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
259// CXX11-ELIDE-NEXT:    10: [B1.9]() (CXXRecordTypedCall, [B1.11], [B1.12])
260// CXX11-NOELIDE-NEXT:    10: [B1.9]() (CXXRecordTypedCall, [B1.11])
261// CXX11-NEXT:    11: [B1.10]
262// CXX11-NEXT:    12: [B1.11] (CXXConstructExpr, [B1.13], class C)
263// CXX11-NEXT:    13: new C([B1.12])
264// CXX11-NEXT:    14: [B1.13] (CXXConstructExpr, c1([B1.13]) (Member initializer), class C)
265// CXX11-NEXT:    15: c1([B1.14]) (Member initializer)
266// CXX17-NEXT:    10: [B1.9]()
267// CXX17-NEXT:    11: new C([B1.10])
268// CXX17-NEXT:    12: [B1.11] (CXXConstructExpr, c1([B1.11]) (Member initializer), class C)
269// CXX17-NEXT:    13: c1([B1.12]) (Member initializer)
270  D(double): C(C::get()), c1(new C(C::get())) {}
271};
272
273// Let's see if initializers work well for fields with destructors.
274class E {
275public:
276  static E get();
277  ~E();
278};
279
280class F {
281  E e;
282
283public:
284// FIXME: There should be no temporary destructor in C++17.
285// CHECK: F()
286// CHECK:          1: E::get
287// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class ctor_initializers::E (*)(
288// CXX11-ELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7])
289// CXX11-NOELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6])
290// CXX11-NEXT:     4: [B1.3] (BindTemporary)
291// CXX11-NEXT:     5: [B1.4] (ImplicitCastExpr, NoOp, const class ctor_initializers::E)
292// CXX11-NEXT:     6: [B1.5]
293// CXX11-NEXT:     7: [B1.6] (CXXConstructExpr, e([B1.6]) (Member initializer), class ctor_initializers
294// CXX11-NEXT:     8: e([B1.7]) (Member initializer)
295// CXX11-NEXT:     9: ~ctor_initializers::E() (Temporary object destructor)
296// CXX17-NEXT:     3: [B1.2]() (CXXRecordTypedCall, e([B1.4]) (Member initializer), [B1.4])
297// CXX17-NEXT:     4: [B1.3] (BindTemporary)
298// CXX17-NEXT:     5: e([B1.4]) (Member initializer)
299// CXX17-NEXT:     6: ~ctor_initializers::E() (Temporary object destructor)
300  F(): e(E::get()) {}
301};
302} // end namespace ctor_initializers
303
304namespace return_stmt_without_dtor {
305
306// CHECK: C returnVariable()
307// CHECK:          1:  (CXXConstructExpr, [B1.2], class C)
308// CHECK-NEXT:     2: C c;
309// CHECK-NEXT:     3: c
310// CHECK-NEXT:     4: [B1.3] (ImplicitCastExpr, NoOp, class C)
311// CHECK-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], class C)
312// CHECK-NEXT:     6: return [B1.5];
313C returnVariable() {
314  C c;
315  return c;
316}
317
318// CHECK: C returnEmptyBraces()
319// CHECK:          1: {} (CXXConstructExpr, [B1.2], class C)
320// CHECK-NEXT:     2: return [B1.1];
321C returnEmptyBraces() {
322  return {};
323}
324
325// CHECK: C returnBracesWithOperatorNew()
326// CHECK:          1: CFGNewAllocator(C *)
327// CHECK-NEXT:     2:  (CXXConstructExpr, [B1.3], class C)
328// CHECK-NEXT:     3: new C([B1.2])
329// CHECK-NEXT:     4: {[B1.3]} (CXXConstructExpr, [B1.5], class C)
330// CHECK-NEXT:     5: return [B1.4];
331C returnBracesWithOperatorNew() {
332  return {new C()};
333}
334
335// CHECK: C returnBracesWithMultipleItems()
336// CHECK:          1: 123
337// CHECK-NEXT:     2: 456
338// CHECK-NEXT:     3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], class C)
339// CHECK-NEXT:     4: return [B1.3];
340C returnBracesWithMultipleItems() {
341  return {123, 456};
342}
343
344// CHECK: C returnTemporary()
345// CXX11-ELIDE:    1: C() (CXXConstructExpr, [B1.2], [B1.3], class C)
346// CXX11-NOELIDE:  1: C() (CXXConstructExpr, [B1.2], class C)
347// CXX11-NEXT:     2: [B1.1]
348// CXX11-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.4], class C)
349// CXX11-NEXT:     4: return [B1.3];
350// CXX17:          1: C() (CXXConstructExpr, [B1.2], class C)
351// CXX17-NEXT:     2: return [B1.1];
352C returnTemporary() {
353  return C();
354}
355
356// CHECK: C returnTemporaryWithArgument()
357// CHECK:          1: nullptr
358// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
359// CXX11-ELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], [B1.6], class C)
360// CXX11-NOELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], class C)
361// CXX17-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.5], class C)
362// CHECK-NEXT:     4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
363// CXX11-NEXT:     5: [B1.4]
364// CXX11-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.7], class C)
365// CXX11-NEXT:     7: return [B1.6];
366// CXX17-NEXT:     5: return [B1.4];
367
368C returnTemporaryWithArgument() {
369  return C(nullptr);
370}
371
372// CHECK: C returnTemporaryConstructedByFunction()
373// CHECK:          1: C::get
374// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
375// CXX11-ELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])
376// CXX11-NOELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
377// CXX11-NEXT:     4: [B1.3]
378// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], class C)
379// CXX11-NEXT:     6: return [B1.5];
380// CXX17-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
381// CXX17-NEXT:     4: return [B1.3];
382C returnTemporaryConstructedByFunction() {
383  return C::get();
384}
385
386// CHECK: C returnChainOfCopies()
387// CHECK:          1: C::get
388// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
389// CXX11-ELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])
390// CXX11-NOELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
391// CXX11-NEXT:     4: [B1.3]
392// CXX11-ELIDE-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.7], [B1.8], class C)
393// CXX11-NOELIDE-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.7], class C)
394// CXX11-NEXT:     6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
395// CXX11-NEXT:     7: [B1.6]
396// CXX11-NEXT:     8: [B1.7] (CXXConstructExpr, [B1.9], class C)
397// CXX11-NEXT:     9: return [B1.8];
398// CXX17-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.5])
399// CXX17-NEXT:     4: C([B1.3]) (CXXFunctionalCastExpr, NoOp, class C)
400// CXX17-NEXT:     5: return [B1.4];
401C returnChainOfCopies() {
402  return C(C::get());
403}
404
405} // end namespace return_stmt_without_dtor
406
407namespace return_stmt_with_dtor {
408
409class D {
410public:
411  D();
412  ~D();
413};
414
415// FIXME: There should be no temporary destructor in C++17.
416// CHECK:  return_stmt_with_dtor::D returnTemporary()
417// CXX11-ELIDE:          1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class return_stmt_with_dtor::D)
418// CXX11-NOELIDE:          1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.2], [B1.4], class return_stmt_with_dtor::D)
419// CXX11-NEXT:     2: [B1.1] (BindTemporary)
420// CXX11-NEXT:     3: [B1.2] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D)
421// CXX11-NEXT:     4: [B1.3]
422// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.7], class return_stmt_with_dtor::D)
423// CXX11-NEXT:     6: ~return_stmt_with_dtor::D() (Temporary object destructor)
424// CXX11-NEXT:     7: return [B1.5];
425// CXX17:          1: return_stmt_with_dtor::D() (CXXConstructExpr, [B1.4], [B1.2], class return_stmt_w
426// CXX17-NEXT:     2: [B1.1] (BindTemporary)
427// CXX17-NEXT:     3: ~return_stmt_with_dtor::D() (Temporary object destructor)
428// CXX17-NEXT:     4: return [B1.2];
429D returnTemporary() {
430  return D();
431}
432
433// FIXME: There should be no temporary destructor in C++17.
434// CHECK: void returnByValueIntoVariable()
435// CHECK:          1: returnTemporary
436// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class return_stmt_with_dtor::D (*)(void))
437// CXX11-ELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7])
438// CXX11-NOELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6])
439// CXX11-NEXT:     4: [B1.3] (BindTemporary)
440// CXX11-NEXT:     5: [B1.4] (ImplicitCastExpr, NoOp, const class return_stmt_with_dtor::D)
441// CXX11-NEXT:     6: [B1.5]
442// CXX11-NEXT:     7: [B1.6] (CXXConstructExpr, [B1.8], class return_stmt_with_dtor::D)
443// CXX11-NEXT:     8: return_stmt_with_dtor::D d = returnTemporary();
444// CXX11-NEXT:     9: ~return_stmt_with_dtor::D() (Temporary object destructor)
445// CXX11-NEXT:    10: [B1.8].~D() (Implicit destructor)
446// CXX17-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.5], [B1.4])
447// CXX17-NEXT:     4: [B1.3] (BindTemporary)
448// CXX17-NEXT:     5: return_stmt_with_dtor::D d = returnTemporary();
449// CXX17-NEXT:     6: ~return_stmt_with_dtor::D() (Temporary object destructor)
450// CXX17-NEXT:     7: [B1.5].~D() (Implicit destructor)
451void returnByValueIntoVariable() {
452  D d = returnTemporary();
453}
454
455} // end namespace return_stmt_with_dtor
456
457namespace temporary_object_expr_without_dtors {
458
459// TODO: Should provide construction context for the constructor,
460// even if there is no specific trigger statement here.
461// CHECK: void simpleTemporary()
462// CHECK           1: C() (CXXConstructExpr, class C)
463void simpleTemporary() {
464  C();
465}
466
467// CHECK: void temporaryInCondition()
468// CHECK:          1: C() (CXXConstructExpr, [B2.2], class C)
469// CHECK-NEXT:     2: [B2.1]
470// CHECK-NEXT:     3: [B2.2] (ImplicitCastExpr, NoOp, const class C)
471// CHECK-NEXT:     4: [B2.3].operator bool
472// CHECK-NEXT:     5: [B2.3]
473// CHECK-NEXT:     6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
474// CHECK-NEXT:     T: if [B2.6]
475void temporaryInCondition() {
476  if (C());
477}
478
479// CHECK: void temporaryInConditionVariable()
480// CXX11-ELIDE:    1: C() (CXXConstructExpr, [B2.2], [B2.3], class C)
481// CXX11-NOELIDE:  1: C() (CXXConstructExpr, [B2.2], class C)
482// CXX11-NEXT:     2: [B2.1]
483// CXX11-NEXT:     3: [B2.2] (CXXConstructExpr, [B2.4], class C)
484// CXX11-NEXT:     4: C c = C();
485// CXX11-NEXT:     5: c
486// CXX11-NEXT:     6: [B2.5] (ImplicitCastExpr, NoOp, const class C)
487// CXX11-NEXT:     7: [B2.6].operator bool
488// CXX11-NEXT:     8: [B2.6]
489// CXX11-NEXT:     9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
490// CXX11-NEXT:     T: if [B2.9]
491// CXX17:          1: C() (CXXConstructExpr, [B2.2], class C)
492// CXX17-NEXT:     2: C c = C();
493// CXX17-NEXT:     3: c
494// CXX17-NEXT:     4: [B2.3] (ImplicitCastExpr, NoOp, const class C)
495// CXX17-NEXT:     5: [B2.4].operator bool
496// CXX17-NEXT:     6: [B2.4]
497// CXX17-NEXT:     7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
498// CXX17-NEXT:     T: if [B2.7]
499void temporaryInConditionVariable() {
500  if (C c = C());
501}
502
503
504// CHECK: void temporaryInForLoopConditionVariable()
505// CHECK:        [B2]
506// CXX11-ELIDE-NEXT:     1: C() (CXXConstructExpr, [B2.2], [B2.3], class C)
507// CXX11-NOELIDE-NEXT:     1: C() (CXXConstructExpr, [B2.2], class C)
508// CXX11-NEXT:     2: [B2.1]
509// CXX11-NEXT:     3: [B2.2] (CXXConstructExpr, [B2.4], class C)
510// CXX11-NEXT:     4: C c2 = C();
511// CXX11-NEXT:     5: c2
512// CXX11-NEXT:     6: [B2.5] (ImplicitCastExpr, NoOp, const class C)
513// CXX11-NEXT:     7: [B2.6].operator bool
514// CXX11-NEXT:     8: [B2.6]
515// CXX11-NEXT:     9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
516// CXX11-NEXT:     T: for (...; [B2.9]; )
517// CXX17-NEXT:     1: C() (CXXConstructExpr, [B2.2], class C)
518// CXX17-NEXT:     2: C c2 = C();
519// CXX17-NEXT:     3: c2
520// CXX17-NEXT:     4: [B2.3] (ImplicitCastExpr, NoOp, const class C)
521// CXX17-NEXT:     5: [B2.4].operator bool
522// CXX17-NEXT:     6: [B2.4]
523// CXX17-NEXT:     7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
524// CXX17-NEXT:     T: for (...; [B2.7]; )
525// CHECK:        [B3]
526// CXX11-ELIDE-NEXT:     1: C() (CXXConstructExpr, [B3.2], [B3.3], class C)
527// CXX11-NOELIDE-NEXT:     1: C() (CXXConstructExpr, [B3.2], class C)
528// CXX11-NEXT:     2: [B3.1]
529// CXX11-NEXT:     3: [B3.2] (CXXConstructExpr, [B3.4], class C)
530// CXX11-NEXT:     4: C c1 = C();
531// CXX17-NEXT:     1: C() (CXXConstructExpr, [B3.2], class C)
532// CXX17-NEXT:     2: C c1 = C();
533void temporaryInForLoopConditionVariable() {
534  for (C c1 = C(); C c2 = C(); );
535}
536
537
538// CHECK: void temporaryInWhileLoopConditionVariable()
539// CXX11-ELIDE:          1: C() (CXXConstructExpr, [B2.2], [B2.3], class C)
540// CXX11-NOELIDE:          1: C() (CXXConstructExpr, [B2.2], class C)
541// CXX11-NEXT:     2: [B2.1]
542// CXX11-NEXT:     3: [B2.2] (CXXConstructExpr, [B2.4], class C)
543// CXX11-NEXT:     4: C c = C();
544// CXX11-NEXT:     5: c
545// CXX11-NEXT:     6: [B2.5] (ImplicitCastExpr, NoOp, const class C)
546// CXX11-NEXT:     7: [B2.6].operator bool
547// CXX11-NEXT:     8: [B2.6]
548// CXX11-NEXT:     9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
549// CXX11-NEXT:     T: while [B2.9]
550// CXX17:          1: C() (CXXConstructExpr, [B2.2], class C)
551// CXX17-NEXT:     2: C c = C();
552// CXX17-NEXT:     3: c
553// CXX17-NEXT:     4: [B2.3] (ImplicitCastExpr, NoOp, const class C)
554// CXX17-NEXT:     5: [B2.4].operator bool
555// CXX17-NEXT:     6: [B2.4]
556// CXX17-NEXT:     7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
557// CXX17-NEXT:     T: while [B2.7]
558void temporaryInWhileLoopConditionVariable() {
559  while (C c = C());
560}
561
562} // end namespace temporary_object_expr_without_dtors
563
564namespace temporary_object_expr_with_dtors {
565
566class D {
567public:
568  D();
569  D(int);
570  ~D();
571
572  static D get();
573
574  operator bool() const;
575};
576
577// CHECK: void simpleTemporary()
578// CHECK:          1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], class temporary_object_expr_with_dtors::D)
579// CHECK-NEXT:     2: [B1.1] (BindTemporary)
580// CHECK-NEXT:     3: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
581void simpleTemporary() {
582  D();
583}
584
585// CHECK:  void temporaryInCondition()
586// CHECK:          1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], [B2.3], class temporary_object_expr_with_dtors::D)
587// CHECK-NEXT:     2: [B2.1] (BindTemporary)
588// CHECK-NEXT:     3: [B2.2]
589// CHECK-NEXT:     4: [B2.3] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
590// CHECK-NEXT:     5: [B2.4].operator bool
591// CHECK-NEXT:     6: [B2.4]
592// CHECK-NEXT:     7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
593// CHECK-NEXT:     8: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
594// CHECK-NEXT:     T: if [B2.7]
595void temporaryInCondition() {
596  if (D());
597}
598
599// CHECK: void referenceVariableWithConstructor()
600// CHECK:          1: 0
601// CHECK-NEXT:     2: [B1.1] (CXXConstructExpr, [B1.4], const class temporary_object_expr_with_dtors::D)
602// CHECK-NEXT:     3: [B1.2] (BindTemporary)
603// CHECK-NEXT:     4: [B1.3]
604// CHECK-NEXT:     5: const temporary_object_expr_with_dtors::D &d(0);
605// CHECK-NEXT:     6: [B1.5].~D() (Implicit destructor)
606void referenceVariableWithConstructor() {
607  const D &d(0);
608}
609
610// CHECK: void referenceVariableWithInitializer()
611// CHECK:          1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.4], class temporary_object_expr_with_dtors::D)
612// CHECK-NEXT:     2: [B1.1] (BindTemporary)
613// CHECK-NEXT:     3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
614// CHECK-NEXT:     4: [B1.3]
615// CHECK-NEXT:     5: const temporary_object_expr_with_dtors::D &d = temporary_object_expr_with_dtors::D();
616// CHECK-NEXT:     6: [B1.5].~D() (Implicit destructor)
617void referenceVariableWithInitializer() {
618  const D &d = D();
619}
620
621// CHECK: void referenceVariableWithTernaryOperator(bool coin)
622// CXX11:        [B1]
623// CXX11-NEXT:     1: [B4.4].~D() (Implicit destructor)
624// CXX11:        [B2]
625// CXX11-NEXT:     1: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
626// CXX11:        [B3]
627// CXX11-NEXT:     1: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
628// CXX11:        [B4]
629// CXX11-NEXT:     1: [B7.2] ? [B5.8] : [B6.8]
630// CXX11-NEXT:     2: [B4.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
631// CXX11-NEXT:     3: [B4.2]
632// CXX11-NEXT:     4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0);
633// CXX11-NEXT:     T: (Temp Dtor) [B6.3]
634// CXX11:        [B5]
635// CXX11-NEXT:     1: D::get
636// CXX11-NEXT:     2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void))
637// CXX11-ELIDE-NEXT:     3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6], [B5.7])
638// CXX11-NOELIDE-NEXT:     3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6])
639// CXX11-NEXT:     4: [B5.3] (BindTemporary)
640// CXX11-NEXT:     5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
641// CXX11-NEXT:     6: [B5.5]
642// CXX11-NEXT:     7: [B5.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D)
643// CXX11-NEXT:     8: [B5.7] (BindTemporary)
644// CXX11:        [B6]
645// CXX11-NEXT:     1: 0
646// CXX11-ELIDE-NEXT:     2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], [B6.7], class temporary_object_expr_with_dtors::D)
647// CXX11-NOELIDE-NEXT:     2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], class temporary_object_expr_with_dtors::D)
648// CXX11-NEXT:     3: [B6.2] (BindTemporary)
649// CXX11-NEXT:     4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
650// CXX11-NEXT:     5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
651// CXX11-NEXT:     6: [B6.5]
652// CXX11-NEXT:     7: [B6.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D)
653// CXX11-NEXT:     8: [B6.7] (BindTemporary)
654// CXX11:        [B7]
655// CXX11-NEXT:     1: coin
656// CXX11-NEXT:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
657// CXX11-NEXT:     T: [B7.2] ? ... : ...
658// CXX17:        [B1]
659// CXX17-NEXT:     1: [B4.2] ? [B2.4] : [B3.4]
660// CXX17-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
661// CXX17-NEXT:     3: [B1.2]
662// CXX17-NEXT:     4: const temporary_object_expr_with_dtors::D &d = coin ? D::get() : temporary_object_expr_with_dtors::D(0);
663// CXX17-NEXT:     5: [B1.4].~D() (Implicit destructor)
664// CXX17:        [B2]
665// CXX17-NEXT:     1: D::get
666// CXX17-NEXT:     2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void))
667// CXX17-NEXT:     3: [B2.2]() (CXXRecordTypedCall, [B1.3])
668// CXX17-NEXT:     4: [B2.3] (BindTemporary)
669// CXX17:        [B3]
670// CXX17-NEXT:     1: 0
671// CXX17-NEXT:     2: [B3.1] (CXXConstructExpr, [B1.3], class temporary_object_expr_with_dtors::D)
672// CXX17-NEXT:     3: [B3.2] (BindTemporary)
673// CXX17-NEXT:     4: temporary_object_expr_with_dtors::D([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
674// CXX17:        [B4]
675// CXX17-NEXT:     1: coin
676// CXX17-NEXT:     2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)
677// CXX17-NEXT:     T: [B4.2] ? ... : ...
678void referenceVariableWithTernaryOperator(bool coin) {
679  const D &d = coin ? D::get() : D(0);
680}
681
682// CHECK: void referenceWithFunctionalCast()
683// CHECK:          1: 1
684// CHECK-NEXT:     2: [B1.1] (CXXConstructExpr, [B1.5], class temporary_object_expr_with_dtors::D)
685// CHECK-NEXT:     3: [B1.2] (BindTemporary)
686// CHECK-NEXT:     4: temporary_object_expr_with_dtors::D([B1.3]) (CXXFunctionalCastExpr, ConstructorCon
687// CHECK-NEXT:     5: [B1.4]
688// CHECK-NEXT:     6: temporary_object_expr_with_dtors::D &&d = temporary_object_expr_with_dtors::D(1);
689// CHECK-NEXT:     7: [B1.6].~D() (Implicit destructor)
690void referenceWithFunctionalCast() {
691  D &&d = D(1);
692}
693
694// Test the condition constructor, we don't care about branch constructors here.
695// CHECK: void constructorInTernaryCondition()
696// CXX11:          1: 1
697// CXX11-NEXT:     2: [B7.1] (CXXConstructExpr, [B7.3], [B7.5], class temporary_object_expr_with_dtors::D)
698// CXX11-NEXT:     3: [B7.2] (BindTemporary)
699// CXX11-NEXT:     4: temporary_object_expr_with_dtors::D([B7.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
700// CXX11-NEXT:     5: [B7.4]
701// CXX11-NEXT:     6: [B7.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
702// CXX11-NEXT:     7: [B7.6].operator bool
703// CXX11-NEXT:     8: [B7.6]
704// CXX11-NEXT:     9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
705// CXX11-NEXT:     T: [B7.9] ? ... : ...
706// CXX17:          1: 1
707// CXX17-NEXT:     2: [B4.1] (CXXConstructExpr, [B4.3], [B4.5], class temporary_object_expr_with_dtors::D)
708// CXX17-NEXT:     3: [B4.2] (BindTemporary)
709// CXX17-NEXT:     4: temporary_object_expr_with_dtors::D([B4.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
710// CXX17-NEXT:     5: [B4.4]
711// CXX17-NEXT:     6: [B4.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
712// CXX17-NEXT:     7: [B4.6].operator bool
713// CXX17-NEXT:     8: [B4.6]
714// CXX17-NEXT:     9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
715// CXX17-NEXT:     T: [B4.9] ? ... : ...
716void constructorInTernaryCondition() {
717  const D &d = D(1) ? D(2) : D(3);
718}
719
720} // end namespace temporary_object_expr_with_dtors
721
722namespace implicit_constructor_conversion {
723
724class A {};
725A get();
726
727class B {
728public:
729  B(const A &);
730  ~B() {}
731};
732
733// CHECK: void implicitConstructionConversionFromTemporary()
734// CHECK:          1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A)
735// CXX11-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
736// CXX11-NEXT:     3: [B1.2]
737// CXX11-ELIDE-NEXT:     4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], [B1.9], class implicit_constructor_conversion::B)
738// CXX11-NOELIDE-NEXT:     4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], class implicit_constructor_conversion::B)
739// CXX11-NEXT:     5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
740// CXX11-NEXT:     6: [B1.5] (BindTemporary)
741// CXX11-NEXT:     7: [B1.6] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
742// CXX11-NEXT:     8: [B1.7]
743// CXX11-NEXT:     9: [B1.8] (CXXConstructExpr, [B1.10], class implicit_constructor_conversion::B)
744// CXX11-NEXT:    10: implicit_constructor_conversion::B b = implicit_constructor_conversion::A();
745// CXX11-NEXT:    11: ~implicit_constructor_conversion::B() (Temporary object destructor)
746// CXX11-NEXT:    12: [B1.10].~B() (Implicit destructor)
747// CXX17-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
748// CXX17-NEXT:     3: [B1.2]
749// CXX17-NEXT:     4: [B1.3] (CXXConstructExpr, [B1.6], class implicit_constructor_conversion::B)
750// CXX17-NEXT:     5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
751// CXX17-NEXT:     6: implicit_constructor_conversion::B b = implicit_constructor_conversion::A();
752// CXX17-NEXT:     7: [B1.6].~B() (Implicit destructor)
753void implicitConstructionConversionFromTemporary() {
754  B b = A();
755}
756
757// CHECK: void implicitConstructionConversionFromFunctionValue()
758// CHECK:          1: get
759// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conversion::A (*)(void))
760// CHECK-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.5])
761// CHECK-NEXT:     4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
762// CHECK-NEXT:     5: [B1.4]
763// CXX11-ELIDE-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class implicit_constructor_conversion::B)
764// CXX11-NOELIDE-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], class implicit_constructor_conversion::B)
765// CXX11-NEXT:     7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
766// CXX11-NEXT:     8: [B1.7] (BindTemporary)
767// CXX11-NEXT:     9: [B1.8] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
768// CXX11-NEXT:    10: [B1.9]
769// CXX11-NEXT:    11: [B1.10] (CXXConstructExpr, [B1.12], class implicit_constructor_conversion::B)
770// CXX11-NEXT:    12: implicit_constructor_conversion::B b = get();
771// CXX11-NEXT:    13: ~implicit_constructor_conversion::B() (Temporary object destructor)
772// CXX11-NEXT:    14: [B1.12].~B() (Implicit destructor)
773// CXX17-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.8], class implicit_constructor_conversion::B)
774// CXX17-NEXT:     7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
775// CXX17-NEXT:     8: implicit_constructor_conversion::B b = get();
776// CXX17-NEXT:     9: [B1.8].~B() (Implicit destructor)
777void implicitConstructionConversionFromFunctionValue() {
778  B b = get();
779}
780
781// CHECK: void implicitConstructionConversionFromTemporaryWithLifetimeExtension()
782// CHECK:          1: implicit_constructor_conversion::A() (CXXConstructExpr, [B1.3], class implicit_constructor_conversion::A)
783// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
784// CHECK-NEXT:     3: [B1.2]
785// CHECK-NEXT:     4: [B1.3] (CXXConstructExpr, [B1.7], class implicit_constructor_conversion::B)
786// CHECK-NEXT:     5: [B1.4] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_conversion::B)
787// CHECK-NEXT:     6: [B1.5] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
788// CHECK-NEXT:     7: [B1.6]
789// CHECK-NEXT:     8: const implicit_constructor_conversion::B &b = implicit_constructor_conversion::A();
790// CHECK-NEXT:     9: [B1.8].~B() (Implicit destructor)
791void implicitConstructionConversionFromTemporaryWithLifetimeExtension() {
792  const B &b = A();
793}
794
795// CHECK: void implicitConstructionConversionFromFunctionValueWithLifetimeExtension()
796// CHECK:          1: get
797// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver
798// CHECK-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.5])
799// CHECK-NEXT:     4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
800// CHECK-NEXT:     5: [B1.4]
801// CHECK-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.9], class implicit_constructor_conversion::B)
802// CHECK-NEXT:     7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers
803// CHECK-NEXT:     8: [B1.7] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::B)
804// CHECK-NEXT:     9: [B1.8]
805// CHECK-NEXT:    10: const implicit_constructor_conversion::B &b = get();
806// CHECK-NEXT:    11: [B1.10].~B() (Implicit destructor)
807void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() {
808  const B &b = get(); // no-crash
809}
810
811} // end namespace implicit_constructor_conversion
812
813namespace argument_constructors {
814class D {
815public:
816  D();
817  ~D();
818};
819
820class E {
821public:
822  E(D d);
823  E(D d1, D d2);
824};
825
826void useC(C c);
827void useCByReference(const C &c);
828void useD(D d);
829void useDByReference(const D &d);
830void useCAndD(C c, D d);
831
832// CHECK: void passArgument()
833// CHECK:          1: useC
834// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C))
835// CXX11-ELIDE-NEXT:     3: C() (CXXConstructExpr, [B1.4], [B1.5], class C)
836// CXX11-NOELIDE-NEXT:     3: C() (CXXConstructExpr, [B1.4], class C)
837// CXX11-NEXT:     4: [B1.3]
838// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6]+0, class C)
839// CXX11-NEXT:     6: [B1.2]([B1.5])
840// CXX17-NEXT:     3: C() (CXXConstructExpr, [B1.4]+0, class C)
841// CXX17-NEXT:     4: [B1.2]([B1.3])
842void passArgument() {
843  useC(C());
844}
845
846// CHECK: void passTwoArguments()
847// CHECK:        [B1]
848// CHECK-NEXT:     1: useCAndD
849// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class C, class argument_constructors::D))
850// CXX11-ELIDE-NEXT:     3: C() (CXXConstructExpr, [B1.4], [B1.5], class C)
851// CXX11-NOELIDE-NEXT:     3: C() (CXXConstructExpr, [B1.4], class C)
852// CXX11-NEXT:     4: [B1.3]
853// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.12]+0, class C)
854// CXX11-ELIDE-NEXT:     6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], [B1.10], class argument_constructors::D)
855// CXX11-NOELIDE-NEXT:     6: argument_constructors::D() (CXXConstructExpr, [B1.7], [B1.9], class argument_constructors::D)
856// CXX11-NEXT:     7: [B1.6] (BindTemporary)
857// CXX11-NEXT:     8: [B1.7] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
858// CXX11-NEXT:     9: [B1.8]
859// CXX11-NEXT:    10: [B1.9] (CXXConstructExpr, [B1.11], [B1.12]+1, class argument_constructors::D)
860// CXX11-NEXT:    11: [B1.10] (BindTemporary)
861// CXX11-NEXT:    12: [B1.2]([B1.5], [B1.11])
862// CXX11-NEXT:    13: ~argument_constructors::D() (Temporary object destructor)
863// CXX11-NEXT:    14: ~argument_constructors::D() (Temporary object destructor)
864// CXX17-NEXT:     3: C() (CXXConstructExpr, [B1.6]+0, class C)
865// CXX17-NEXT:     4: argument_constructors::D() (CXXConstructExpr, [B1.5], [B1.6]+1, class argument_co
866// CXX17-NEXT:     5: [B1.4] (BindTemporary)
867// CXX17-NEXT:     6: [B1.2]([B1.3], [B1.5])
868// CXX17-NEXT:     7: ~argument_constructors::D() (Temporary object destructor)
869void passTwoArguments() {
870  useCAndD(C(), D());
871}
872
873// CHECK: void passArgumentByReference()
874// CHECK:          1: useCByReference
875// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class C &))
876// CHECK-NEXT:     3: C() (CXXConstructExpr, [B1.5], class C)
877// CHECK-NEXT:     4: [B1.3] (ImplicitCastExpr, NoOp, const class C)
878// CHECK-NEXT:     5: [B1.4]
879// CHECK-NEXT:     6: [B1.2]([B1.5])
880void passArgumentByReference() {
881  useCByReference(C());
882}
883
884// CHECK: void passArgumentWithDestructor()
885// CHECK:          1: useD
886// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(class argument_constructors::D))
887// CXX11-ELIDE-NEXT:     3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], class argument_constructors::D)
888// CXX11-NOELIDE-NEXT:     3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_constructors::D)
889// CXX11-NEXT:     4: [B1.3] (BindTemporary)
890// CXX11-NEXT:     5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
891// CXX11-NEXT:     6: [B1.5]
892// CXX11-NEXT:     7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, class argument_constructors::D)
893// CXX11-NEXT:     8: [B1.7] (BindTemporary)
894// CXX11-NEXT:     9: [B1.2]([B1.8])
895// CXX11-NEXT:    10: ~argument_constructors::D() (Temporary object destructor)
896// CXX11-NEXT:    11: ~argument_constructors::D() (Temporary object destructor)
897// CXX17-NEXT:     3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+0, class argument_constructors::D)
898// CXX17-NEXT:     4: [B1.3] (BindTemporary)
899// CXX17-NEXT:     5: [B1.2]([B1.4])
900// CXX17-NEXT:     6: ~argument_constructors::D() (Temporary object destructor)
901void passArgumentWithDestructor() {
902  useD(D());
903}
904
905// CHECK: void passArgumentWithDestructorByReference()
906// CHECK:          1: useDByReference
907// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class argumen
908// CHECK-NEXT:     3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.6], class argument_c
909// CHECK-NEXT:     4: [B1.3] (BindTemporary)
910// CHECK-NEXT:     5: [B1.4] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
911// CHECK-NEXT:     6: [B1.5]
912// CHECK-NEXT:     7: [B1.2]([B1.6])
913// CHECK-NEXT:     8: ~argument_constructors::D() (Temporary object destructor)
914void passArgumentWithDestructorByReference() {
915  useDByReference(D());
916}
917
918// CHECK: void passArgumentIntoAnotherConstructor()
919// CXX11-ELIDE:          1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D)
920// CXX11-NOELIDE:          1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D)
921// CXX11-NEXT:     2: [B1.1] (BindTemporary)
922// CXX11-NEXT:     3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
923// CXX11-NEXT:     4: [B1.3]
924// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], [B1.7]+0, class argument_constructors::D)
925// CXX11-NEXT:     6: [B1.5] (BindTemporary)
926// CXX11-ELIDE-NEXT:     7: [B1.6] (CXXConstructExpr, [B1.9], [B1.10], class argument_constructors::E)
927// CXX11-NOELIDE-NEXT:     7: [B1.6] (CXXConstructExpr, [B1.9], class argument_constructors::E)
928// CXX11-NEXT:     8: argument_constructors::E([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E)
929// CXX11-NEXT:     9: [B1.8]
930// CXX11-NEXT:    10: [B1.9] (CXXConstructExpr, [B1.11], class argument_constructors::E)
931// CXX11-NEXT:    11: argument_constructors::E e = argument_constructors::E(argument_constructors::D());
932// CXX11-NEXT:    12: ~argument_constructors::D() (Temporary object destructor)
933// CXX11-NEXT:    13: ~argument_constructors::D() (Temporary object destructor)
934// CXX17:          1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.3]+0, class argument_constructors::D)
935// CXX17-NEXT:     2: [B1.1] (BindTemporary)
936// CXX17-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.5], class argument_constructors::E)
937// CXX17-NEXT:     4: argument_constructors::E([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class argument_constructors::E)
938// CXX17-NEXT:     5: argument_constructors::E e = argument_constructors::E(argument_constructors::D());
939// CXX17-NEXT:     6: ~argument_constructors::D() (Temporary object destructor)
940void passArgumentIntoAnotherConstructor() {
941  E e = E(D());
942}
943
944
945// CHECK: void passTwoArgumentsIntoAnotherConstructor()
946// CXX11-ELIDE:          1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D)
947// CXX11-NOELIDE:          1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D)
948// CXX11-NEXT:     2: [B1.1] (BindTemporary)
949// CXX11-NEXT:     3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
950// CXX11-NEXT:     4: [B1.3]
951// CXX11-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class argument_constructors::D)
952// CXX11-NEXT:     6: [B1.5] (BindTemporary)
953// CXX11-ELIDE-NEXT:     7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class argument_constructors::D)
954// CXX11-NOELIDE-NEXT:     7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], class argument_constructors::D)
955// CXX11-NEXT:     8: [B1.7] (BindTemporary)
956// CXX11-NEXT:     9: [B1.8] (ImplicitCastExpr, NoOp, const class argument_constructors::D)
957// CXX11-NEXT:    10: [B1.9]
958// CXX11-NEXT:    11: [B1.10] (CXXConstructExpr, [B1.12], [B1.13]+1, class argument_constructors::D)
959// CXX11-NEXT:    12: [B1.11] (BindTemporary)
960// CXX11-NEXT:    13: argument_constructors::E([B1.6], [B1.12]) (CXXConstructExpr, class argument_constructors::E)
961// CXX11-NEXT:    14: ~argument_constructors::D() (Temporary object destructor)
962// CXX11-NEXT:    15: ~argument_constructors::D() (Temporary object destructor)
963// CXX11-NEXT:    16: ~argument_constructors::D() (Temporary object destructor)
964// CXX11-NEXT:    17: ~argument_constructors::D() (Temporary object destructor)
965// CXX17:          1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.5]+0, class argument_constructors::D)
966// CXX17-NEXT:     2: [B1.1] (BindTemporary)
967// CXX17-NEXT:     3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+1, class argument_constructors::D)
968// CXX17-NEXT:     4: [B1.3] (BindTemporary)
969// CXX17-NEXT:     5: argument_constructors::E([B1.2], [B1.4]) (CXXConstructExpr, class argument_constructors::E)
970// CXX17-NEXT:     6: ~argument_constructors::D() (Temporary object destructor)
971// CXX17-NEXT:     7: ~argument_constructors::D() (Temporary object destructor)
972void passTwoArgumentsIntoAnotherConstructor() {
973  E(D(), D());
974}
975} // end namespace argument_constructors
976
977namespace copy_elision_with_extra_arguments {
978class C {
979public:
980  C();
981  C(const C &c, int x = 0);
982};
983
984// CHECK: void testCopyElisionWhenCopyConstructorHasExtraArguments()
985// CHECK:        [B1]
986// CXX11-ELIDE-NEXT:     1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.3], [B1.5], class copy_elision_with_extra_arguments::C)
987// CXX11-NOELIDE-NEXT:     1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.3], class copy_elision_with_extra_arguments::C)
988// CXX11-NEXT:     2: [B1.1] (ImplicitCastExpr, NoOp, const class copy_elision_with_extra_arguments::C)
989// CXX11-NEXT:     3: [B1.2]
990// CXX11-NEXT:     4:
991// CXX11-NEXT:     5: [B1.3] (CXXConstructExpr, [B1.6], class copy_elision_with_extra_arguments::C)
992// CXX11-NEXT:     6: copy_elision_with_extra_arguments::C c = copy_elision_with_extra_arguments::C();
993// CXX17-NEXT:     1: copy_elision_with_extra_arguments::C() (CXXConstructExpr, [B1.2], class copy_elision_with_extra_arguments::C)
994// CXX17-NEXT:     2: copy_elision_with_extra_arguments::C c = copy_elision_with_extra_arguments::C();
995void testCopyElisionWhenCopyConstructorHasExtraArguments() {
996  C c = C();
997}
998} // namespace copy_elision_with_extra_arguments
999
1000
1001namespace operators {
1002class C {
1003public:
1004  C(int);
1005  C &operator+(C Other);
1006};
1007
1008// FIXME: Find construction context for the this-argument of the operator.
1009// CHECK: void testOperators()
1010// CHECK:        [B1]
1011// CHECK-NEXT:     1: operator+
1012// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class operators::C &(*)(class o
1013// CHECK-NEXT:     3: 1
1014// CHECK-NEXT:     4: [B1.3] (CXXConstructExpr, [B1.6], class operators::C)
1015// CHECK-NEXT:     5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operato
1016// CHECK-NEXT:     6: [B1.5]
1017// CHECK-NEXT:     7: 2
1018// CXX11-ELIDE-NEXT:     8: [B1.7] (CXXConstructExpr, [B1.10], [B1.11], class operators::C)
1019// CXX11-NOELIDE-NEXT:     8: [B1.7] (CXXConstructExpr, [B1.10], class operators::C)
1020// CXX11-NEXT:     9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato
1021// CXX11-NEXT:    10: [B1.9]
1022// CXX11-NEXT:    11: [B1.10] (CXXConstructExpr, [B1.12]+1, class operators::C)
1023// CXX11-NEXT:    12: [B1.6] + [B1.11] (OperatorCall)
1024// CXX17-NEXT:     8: [B1.7] (CXXConstructExpr, [B1.10]+1, class operators::C)
1025// CXX17-NEXT:     9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato
1026// CXX17-NEXT:    10: [B1.6] + [B1.9] (OperatorCall)
1027void testOperators() {
1028  C(1) + C(2);
1029}
1030} // namespace operators
1031
1032namespace variadic_function_arguments {
1033class C {
1034 public:
1035  C(int);
1036};
1037
1038int variadic(...);
1039
1040// This code is quite exotic, so let's not test the CFG for it,
1041// but only make sure we don't crash.
1042void testCrashOnVariadicArgument() {
1043  C c(variadic(0 ? c : 0)); // no-crash
1044}
1045} // namespace variadic_function_arguments
1046
1047// CHECK: void testTransparentInitListExprs()
1048// CHECK:        [B1]
1049// CHECK-NEXT:     1: getC
1050// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class transparent_init_list_exprs::C (*)(void))
1051// CXX11-ELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])
1052// CXX11-NOELIDE-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.4])
1053// CXX11-NEXT:     4: [B1.3]
1054// CXX11-NEXT:     5: {[B1.4]} (CXXConstructExpr, [B1.6], class transparent_init_list_exprs::C)
1055// CXX11-NEXT:     6: transparent_init_list_exprs::C c{getC()};
1056// CXX17-NEXT:     3: [B1.2]() (CXXRecordTypedCall, [B1.5])
1057// CXX17-NEXT:     4: {[B1.3]}
1058// CXX17-NEXT:     5: transparent_init_list_exprs::C c{getC()};
1059namespace transparent_init_list_exprs {
1060class C {};
1061C getC();
1062void testTransparentInitListExprs() {
1063  C c{getC()};
1064}
1065} // namespace transparent_init_list_exprs
1066