blob: 28cc440c46fcb27b3bd4af3a8225c7c32424164f [file] [log] [blame]
Manuel Klimekb0042c42014-07-30 08:34:42 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +00002// RUN: FileCheck --input-file=%t %s
Will Dietzdf9a2bb2013-01-07 09:51:17 +00003
Jordan Rosee02e96a2014-01-15 17:25:05 +00004// CHECK-LABEL: void checkWrap(int i)
Will Dietzdf9a2bb2013-01-07 09:51:17 +00005// CHECK: ENTRY
6// CHECK-NEXT: Succs (1): B1
7// CHECK: [B1]
8// CHECK: Succs (21): B2 B3 B4 B5 B6 B7 B8 B9
9// CHECK: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19
10// CHECK: B20 B21 B0
11// CHECK: [B0 (EXIT)]
12// CHECK-NEXT: Preds (21): B2 B3 B4 B5 B6 B7 B8 B9
13// CHECK-NEXT: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19
14// CHECK-NEXT: B20 B21 B1
Jordan Rose5250b872013-06-03 22:59:41 +000015void checkWrap(int i) {
Will Dietzdf9a2bb2013-01-07 09:51:17 +000016 switch(i) {
17 case 0: break;
18 case 1: break;
19 case 2: break;
20 case 3: break;
21 case 4: break;
22 case 5: break;
23 case 6: break;
24 case 7: break;
25 case 8: break;
26 case 9: break;
27 case 10: break;
28 case 11: break;
29 case 12: break;
30 case 13: break;
31 case 14: break;
32 case 15: break;
33 case 16: break;
34 case 17: break;
35 case 18: break;
36 case 19: break;
37 }
38}
Jordan Rose5250b872013-06-03 22:59:41 +000039
Jordan Rosee02e96a2014-01-15 17:25:05 +000040// CHECK-LABEL: void checkDeclStmts()
Jordan Rose5250b872013-06-03 22:59:41 +000041// CHECK: ENTRY
42// CHECK-NEXT: Succs (1): B1
43// CHECK: [B1]
44// CHECK-NEXT: 1: int i;
45// CHECK-NEXT: 2: int j;
46// CHECK-NEXT: 3: 1
47// CHECK-NEXT: 4: int k = 1;
48// CHECK-NEXT: 5: int l;
49// CHECK-NEXT: 6: 2
50// CHECK-NEXT: 7: int m = 2;
51// CHECK-NEXT: CXXConstructExpr
52// CHECK-NEXT: 9: struct standalone myStandalone;
53// CHECK-NEXT: CXXConstructExpr
David Blaikieabe1a392014-04-02 05:58:29 +000054// CHECK-NEXT: 11: struct (anonymous struct at {{.*}}) myAnon;
Jordan Rose5250b872013-06-03 22:59:41 +000055// CHECK-NEXT: CXXConstructExpr
56// CHECK-NEXT: 13: struct named myNamed;
57// CHECK-NEXT: Preds (1): B2
58// CHECK-NEXT: Succs (1): B0
59void checkDeclStmts() {
60 int i, j;
61 int k = 1, l, m = 2;
62
63 struct standalone { int x, y; };
64 struct standalone myStandalone;
65
66 struct { int x, y; } myAnon;
67
68 struct named { int x, y; } myNamed;
69
70 static_assert(1, "abc");
71}
David Majnemerf69ce862013-06-04 17:38:44 +000072
Jordan Rosee02e96a2014-01-15 17:25:05 +000073// CHECK-LABEL: void F(EmptyE e)
David Majnemerf69ce862013-06-04 17:38:44 +000074// CHECK: ENTRY
75// CHECK-NEXT: Succs (1): B1
76// CHECK: [B1]
77// CHECK-NEXT: 1: e
78// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, enum EmptyE)
79// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, IntegralCast, int)
80// CHECK-NEXT: T: switch [B1.3]
81// CHECK-NEXT: Preds (1): B2
82// CHECK-NEXT: Succs (1): B0
83// CHECK: [B0 (EXIT)]
84// CHECK-NEXT: Preds (1): B1
85enum EmptyE {};
86void F(EmptyE e) {
87 switch (e) {}
88}
Jordan Rose5374c072013-08-19 16:27:28 +000089
Jordan Rosee02e96a2014-01-15 17:25:05 +000090// CHECK-LABEL: void testBuiltinSize()
Jordan Rose5374c072013-08-19 16:27:28 +000091// CHECK: ENTRY
92// CHECK-NEXT: Succs (1): B1
93// CHECK: [B1]
94// CHECK-NEXT: 1: __builtin_object_size
95// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, BuiltinFnToFnPtr, unsigned long (*)(const void *, int))
96// CHECK-NEXT: 3: [B1.2](dummy(), 0)
97// CHECK-NEXT: 4: (void)[B1.3] (CStyleCastExpr, ToVoid, void)
98// CHECK-NEXT: Preds (1): B2
99// CHECK-NEXT: Succs (1): B0
100// CHECK: [B0 (EXIT)]
101// CHECK-NEXT: Preds (1): B1
102void testBuiltinSize() {
103 extern int *dummy();
104 (void)__builtin_object_size(dummy(), 0);
105}
Jordan Rosed2f40792013-09-03 17:00:57 +0000106
107
108class A {
109public:
110 A() {}
111 ~A() {}
112};
113
Jordan Rosee02e96a2014-01-15 17:25:05 +0000114// CHECK-LABEL: void test_deletedtor()
Jordan Rosed2f40792013-09-03 17:00:57 +0000115// CHECK: [B2 (ENTRY)]
116// CHECK-NEXT: Succs (1): B1
117// CHECK: [B1]
Jordan Rosec9176072014-01-13 17:59:19 +0000118// CHECK-NEXT: 1: CFGNewAllocator(A *)
119// CHECK-NEXT: 2: (CXXConstructExpr, class A)
120// CHECK-NEXT: 3: new A([B1.2])
121// CHECK-NEXT: 4: A *a = new A();
122// CHECK-NEXT: 5: a
123// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *)
124// CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor)
125// CHECK-NEXT: 8: delete [B1.6]
Jordan Rosed2f40792013-09-03 17:00:57 +0000126// CHECK-NEXT: Preds (1): B2
127// CHECK-NEXT: Succs (1): B0
128// CHECK: [B0 (EXIT)]
129// CHECK-NEXT: Preds (1): B1
130void test_deletedtor() {
131 A *a = new A();
132 delete a;
133}
134
Jordan Rosee02e96a2014-01-15 17:25:05 +0000135// CHECK-LABEL: void test_deleteArraydtor()
Jordan Rosed2f40792013-09-03 17:00:57 +0000136// CHECK: [B2 (ENTRY)]
137// CHECK-NEXT: Succs (1): B1
138// CHECK: [B1]
139// CHECK-NEXT: 1: 5
Jordan Rosec9176072014-01-13 17:59:19 +0000140// CHECK-NEXT: 2: CFGNewAllocator(A *)
141// CHECK-NEXT: 3: (CXXConstructExpr, class A)
142// CHECK-NEXT: 4: new A {{\[\[}}B1.1]]
143// CHECK-NEXT: 5: A *a = new A [5];
144// CHECK-NEXT: 6: a
145// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, class A *)
146// CHECK-NEXT: 8: [B1.7]->~A() (Implicit destructor)
147// CHECK-NEXT: 9: delete [] [B1.7]
Jordan Rosed2f40792013-09-03 17:00:57 +0000148// CHECK-NEXT: Preds (1): B2
149// CHECK-NEXT: Succs (1): B0
150// CHECK: [B0 (EXIT)]
151// CHECK-NEXT: Preds (1): B1
152void test_deleteArraydtor() {
153 A *a = new A[5];
154 delete[] a;
155}
Pavel Labath921e7652013-09-06 08:12:48 +0000156
157
158namespace NoReturnSingleSuccessor {
159 struct A {
160 A();
161 ~A();
162 };
163
164 struct B : public A {
165 B();
166 ~B() __attribute__((noreturn));
167 };
168
Jordan Rosee02e96a2014-01-15 17:25:05 +0000169// CHECK-LABEL: int test1(int *x)
Pavel Labath921e7652013-09-06 08:12:48 +0000170// CHECK: 1: 1
171// CHECK-NEXT: 2: return
172// CHECK-NEXT: ~B() (Implicit destructor)
173// CHECK-NEXT: Preds (1)
174// CHECK-NEXT: Succs (1): B0
175 int test1(int *x) {
176 B b;
177 if (x)
178 return 1;
179 }
180
Jordan Rosee02e96a2014-01-15 17:25:05 +0000181// CHECK-LABEL: int test2(int *x)
Pavel Labath921e7652013-09-06 08:12:48 +0000182// CHECK: 1: 1
183// CHECK-NEXT: 2: return
184// CHECK-NEXT: destructor
185// CHECK-NEXT: Preds (1)
186// CHECK-NEXT: Succs (1): B0
187 int test2(int *x) {
188 const A& a = B();
189 if (x)
190 return 1;
191 }
192}
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000193
194// Test CFG support for "extending" an enum.
Jordan Rosee02e96a2014-01-15 17:25:05 +0000195// CHECK-LABEL: int test_enum_with_extension(enum MyEnum value)
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000196// CHECK: [B7 (ENTRY)]
197// CHECK-NEXT: Succs (1): B2
198// CHECK: [B1]
199// CHECK-NEXT: 1: x
200// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
201// CHECK-NEXT: 3: return [B1.2];
Ted Kremenek9238c5c2014-02-27 21:56:44 +0000202// CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable)
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000203// CHECK-NEXT: Succs (1): B0
204// CHECK: [B2]
205// CHECK-NEXT: 1: 0
206// CHECK-NEXT: 2: int x = 0;
207// CHECK-NEXT: 3: value
208// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)
209// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int)
210// CHECK-NEXT: T: switch [B2.5]
211// CHECK-NEXT: Preds (1): B7
Ted Kremenek9238c5c2014-02-27 21:56:44 +0000212// CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable)
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000213// CHECK: [B3]
214// CHECK-NEXT: case D:
215// CHECK-NEXT: 1: 4
216// CHECK-NEXT: 2: x
217// CHECK-NEXT: 3: [B3.2] = [B3.1]
218// CHECK-NEXT: T: break;
219// CHECK-NEXT: Preds (1): B2
220// CHECK-NEXT: Succs (1): B1
221// CHECK: [B4]
222// CHECK-NEXT: case C:
223// CHECK-NEXT: 1: 3
224// CHECK-NEXT: 2: x
225// CHECK-NEXT: 3: [B4.2] = [B4.1]
226// CHECK-NEXT: T: break;
227// CHECK-NEXT: Preds (1): B2
228// CHECK-NEXT: Succs (1): B1
229// CHECK: [B5]
230// CHECK-NEXT: case B:
231// CHECK-NEXT: 1: 2
232// CHECK-NEXT: 2: x
233// CHECK-NEXT: 3: [B5.2] = [B5.1]
234// CHECK-NEXT: T: break;
235// CHECK-NEXT: Preds (1): B2
236// CHECK-NEXT: Succs (1): B1
237// CHECK: [B6]
238// CHECK-NEXT: case A:
239// CHECK-NEXT: 1: 1
240// CHECK-NEXT: 2: x
241// CHECK-NEXT: 3: [B6.2] = [B6.1]
242// CHECK-NEXT: T: break;
243// CHECK-NEXT: Preds (1): B2
244// CHECK-NEXT: Succs (1): B1
245// CHECK: [B0 (EXIT)]
246// CHECK-NEXT: Preds (1): B1
247enum MyEnum { A, B, C };
248static const enum MyEnum D = (enum MyEnum) 32;
249
250int test_enum_with_extension(enum MyEnum value) {
251 int x = 0;
252 switch (value) {
253 case A: x = 1; break;
254 case B: x = 2; break;
255 case C: x = 3; break;
256 case D: x = 4; break;
257 }
258 return x;
259}
260
Jordan Rosee02e96a2014-01-15 17:25:05 +0000261// CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000262// CHECK: [B7 (ENTRY)]
263// CHECK-NEXT: Succs (1): B2
264// CHECK: [B1]
265// CHECK-NEXT: 1: x
266// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
267// CHECK-NEXT: 3: return [B1.2];
268// CHECK-NEXT: Preds (4): B3 B4 B5 B6
269// CHECK-NEXT: Succs (1): B0
270// CHECK: [B2]
271// CHECK-NEXT: 1: 0
272// CHECK-NEXT: 2: int x = 0;
273// CHECK-NEXT: 3: value
274// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)
275// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int)
276// CHECK-NEXT: T: switch [B2.5]
277// CHECK-NEXT: Preds (1): B7
Ted Kremenek9238c5c2014-02-27 21:56:44 +0000278// CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable)
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000279// CHECK: [B3]
280// CHECK-NEXT: default:
281// CHECK-NEXT: 1: 4
282// CHECK-NEXT: 2: x
283// CHECK-NEXT: 3: [B3.2] = [B3.1]
284// CHECK-NEXT: T: break;
Ted Kremenek9238c5c2014-02-27 21:56:44 +0000285// CHECK-NEXT: Preds (1): B2(Unreachable)
Ted Kremenek5d0fb1e2013-12-11 23:44:05 +0000286// CHECK-NEXT: Succs (1): B1
287// CHECK: [B4]
288// CHECK-NEXT: case C:
289// CHECK-NEXT: 1: 3
290// CHECK-NEXT: 2: x
291// CHECK-NEXT: 3: [B4.2] = [B4.1]
292// CHECK-NEXT: T: break;
293// CHECK-NEXT: Preds (1): B2
294// CHECK-NEXT: Succs (1): B1
295// CHECK: [B5]
296// CHECK-NEXT: case B:
297// CHECK-NEXT: 1: 2
298// CHECK-NEXT: 2: x
299// CHECK-NEXT: 3: [B5.2] = [B5.1]
300// CHECK-NEXT: T: break;
301// CHECK-NEXT: Preds (1): B2
302// CHECK-NEXT: Succs (1): B1
303// CHECK: [B6]
304// CHECK-NEXT: case A:
305// CHECK-NEXT: 1: 1
306// CHECK-NEXT: 2: x
307// CHECK-NEXT: 3: [B6.2] = [B6.1]
308// CHECK-NEXT: T: break;
309// CHECK-NEXT: Preds (1): B2
310// CHECK-NEXT: Succs (1): B1
311// CHECK: [B0 (EXIT)]
312// CHECK-NEXT: Preds (1): B1
313int test_enum_with_extension_default(enum MyEnum value) {
314 int x = 0;
315 switch (value) {
316 case A: x = 1; break;
317 case B: x = 2; break;
318 case C: x = 3; break;
319 default: x = 4; break;
320 }
321 return x;
Jordan Rosec9176072014-01-13 17:59:19 +0000322}
323
324
Jordan Rosee02e96a2014-01-15 17:25:05 +0000325// CHECK-LABEL: void test_placement_new()
Jordan Rosec9176072014-01-13 17:59:19 +0000326// CHECK: [B2 (ENTRY)]
327// CHECK-NEXT: Succs (1): B1
328// CHECK: [B1]
329// CHECK-NEXT: 1: int buffer[16];
330// CHECK-NEXT: 2: buffer
331// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
332// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)
333// CHECK-NEXT: 5: CFGNewAllocator(MyClass *)
334// CHECK-NEXT: 6: (CXXConstructExpr, class MyClass)
335// CHECK-NEXT: 7: new ([B1.4]) MyClass([B1.6])
336// CHECK-NEXT: 8: MyClass *obj = new (buffer) MyClass();
337// CHECK-NEXT: Preds (1): B2
338// CHECK-NEXT: Succs (1): B0
339// CHECK: [B0 (EXIT)]
340// CHECK-NEXT: Preds (1): B1
341
342extern void* operator new (unsigned long sz, void* v);
343extern void* operator new[] (unsigned long sz, void* ptr);
344
345class MyClass {
346public:
347 MyClass() {}
348 ~MyClass() {}
349};
350
351void test_placement_new() {
352 int buffer[16];
353 MyClass* obj = new (buffer) MyClass();
354}
355
Jordan Rosee02e96a2014-01-15 17:25:05 +0000356// CHECK-LABEL: void test_placement_new_array()
Jordan Rosec9176072014-01-13 17:59:19 +0000357// CHECK: [B2 (ENTRY)]
358// CHECK-NEXT: Succs (1): B1
359// CHECK: [B1]
360// CHECK-NEXT: 1: int buffer[16];
361// CHECK-NEXT: 2: buffer
362// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
363// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)
364// CHECK-NEXT: 5: 5
365// CHECK-NEXT: 6: CFGNewAllocator(MyClass *)
366// CHECK-NEXT: 7: (CXXConstructExpr, class MyClass)
367// CHECK-NEXT: 8: new ([B1.4]) MyClass {{\[\[}}B1.5]]
368// CHECK-NEXT: 9: MyClass *obj = new (buffer) MyClass [5];
369// CHECK-NEXT: Preds (1): B2
370// CHECK-NEXT: Succs (1): B0
371// CHECK: [B0 (EXIT)]
372// CHECK-NEXT: Preds (1): B1
373
374void test_placement_new_array() {
375 int buffer[16];
376 MyClass* obj = new (buffer) MyClass[5];
377}
Jordan Rose6f5f7192014-01-14 17:29:12 +0000378
379
Manuel Klimekb0042c42014-07-30 08:34:42 +0000380// CHECK-LABEL: void test_lifetime_extended_temporaries()
381// CHECK: [B1]
382struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); };
383struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; };
384struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; };
385void test_lifetime_extended_temporaries() {
386 // CHECK: LifetimeExtend(1);
387 // CHECK-NEXT: : 1
388 // CHECK-NEXT: ~LifetimeExtend()
389 // CHECK-NOT: ~LifetimeExtend()
390 {
391 const LifetimeExtend &l = LifetimeExtend(1);
392 1;
393 }
394 // CHECK: LifetimeExtend(2)
395 // CHECK-NEXT: ~LifetimeExtend()
396 // CHECK-NEXT: : 2
397 // CHECK-NOT: ~LifetimeExtend()
398 {
399 // No life-time extension.
400 const int &l = (LifetimeExtend(2), 2);
401 2;
402 }
403 // CHECK: LifetimeExtend(3)
404 // CHECK-NEXT: : 3
405 // CHECK-NEXT: ~LifetimeExtend()
406 // CHECK-NOT: ~LifetimeExtend()
407 {
408 // The last one is lifetime extended.
409 const LifetimeExtend &l = (3, LifetimeExtend(3));
410 3;
411 }
412 // CHECK: LifetimeExtend(4)
413 // CHECK-NEXT: ~LifetimeExtend()
414 // CHECK-NEXT: ~LifetimeExtend()
415 // CHECK-NEXT: : 4
416 // CHECK-NOT: ~LifetimeExtend()
417 {
418 Aggregate a{LifetimeExtend(4), LifetimeExtend(4)};
419 4;
420 }
421 // CHECK: LifetimeExtend(5)
422 // CHECK-NEXT: : 5
423 // FIXME: We want to emit the destructors of the lifetime
424 // extended variables here.
425 // CHECK-NOT: ~LifetimeExtend()
426 {
427 AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)};
428 5;
429 }
430 // FIXME: Add tests for lifetime extension via subobject
431 // references (LifetimeExtend().some_member).
432}
433
434
Jordan Rosee02e96a2014-01-15 17:25:05 +0000435// CHECK-LABEL: int *PR18472()
Jordan Rose6f5f7192014-01-14 17:29:12 +0000436// CHECK: [B2 (ENTRY)]
437// CHECK-NEXT: Succs (1): B1
438// CHECK: [B1]
439// CHECK-NEXT: 1: 0
440// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)
441// CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)
442// CHECK-NEXT: 4: CFGNewAllocator(int *)
443// CHECK-NEXT: 5: new (([B1.3])) int
444// CHECK-NEXT: 6: return [B1.5];
445// CHECK-NEXT: Preds (1): B2
446// CHECK-NEXT: Succs (1): B0
447// CHECK: [B0 (EXIT)]
448// CHECK-NEXT: Preds (1): B1
449
450extern "C" typedef int *PR18472_t;
451void *operator new (unsigned long, PR18472_t);
452template <class T> T *PR18472() {
453 return new (((PR18472_t) 0)) T;
454}
455void PR18472_helper() {
456 PR18472<int>();
457}
458