1 // 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
2 // RUN: FileCheck --input-file=%t %s
3
4 // CHECK-LABEL: void checkWrap(int i)
5 // 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
checkWrap(int i)15 void checkWrap(int i) {
16 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 }
39
40 // CHECK-LABEL: void checkDeclStmts()
41 // 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
54 // CHECK-NEXT: 11: struct (anonymous struct at {{.*}}) myAnon;
55 // CHECK-NEXT: CXXConstructExpr
56 // CHECK-NEXT: 13: struct named myNamed;
57 // CHECK-NEXT: Preds (1): B2
58 // CHECK-NEXT: Succs (1): B0
checkDeclStmts()59 void 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 }
72
73 // CHECK-LABEL: void F(EmptyE e)
74 // 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
85 enum EmptyE {};
F(EmptyE e)86 void F(EmptyE e) {
87 switch (e) {}
88 }
89
90 // CHECK-LABEL: void testBuiltinSize()
91 // 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
testBuiltinSize()102 void testBuiltinSize() {
103 extern int *dummy();
104 (void)__builtin_object_size(dummy(), 0);
105 }
106
107
108 class A {
109 public:
A()110 A() {}
~A()111 ~A() {}
112 };
113
114 // CHECK-LABEL: void test_deletedtor()
115 // CHECK: [B2 (ENTRY)]
116 // CHECK-NEXT: Succs (1): B1
117 // CHECK: [B1]
118 // 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]
126 // CHECK-NEXT: Preds (1): B2
127 // CHECK-NEXT: Succs (1): B0
128 // CHECK: [B0 (EXIT)]
129 // CHECK-NEXT: Preds (1): B1
test_deletedtor()130 void test_deletedtor() {
131 A *a = new A();
132 delete a;
133 }
134
135 // CHECK-LABEL: void test_deleteArraydtor()
136 // CHECK: [B2 (ENTRY)]
137 // CHECK-NEXT: Succs (1): B1
138 // CHECK: [B1]
139 // CHECK-NEXT: 1: 5
140 // 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]
148 // CHECK-NEXT: Preds (1): B2
149 // CHECK-NEXT: Succs (1): B0
150 // CHECK: [B0 (EXIT)]
151 // CHECK-NEXT: Preds (1): B1
test_deleteArraydtor()152 void test_deleteArraydtor() {
153 A *a = new A[5];
154 delete[] a;
155 }
156
157
158 namespace NoReturnSingleSuccessor {
159 struct A {
160 A();
161 ~A();
162 };
163
164 struct B : public A {
165 B();
166 ~B() __attribute__((noreturn));
167 };
168
169 // CHECK-LABEL: int test1(int *x)
170 // 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
test1(int * x)175 int test1(int *x) {
176 B b;
177 if (x)
178 return 1;
179 }
180
181 // CHECK-LABEL: int test2(int *x)
182 // CHECK: 1: 1
183 // CHECK-NEXT: 2: return
184 // CHECK-NEXT: destructor
185 // CHECK-NEXT: Preds (1)
186 // CHECK-NEXT: Succs (1): B0
test2(int * x)187 int test2(int *x) {
188 const A& a = B();
189 if (x)
190 return 1;
191 }
192 }
193
194 // Test CFG support for "extending" an enum.
195 // CHECK-LABEL: int test_enum_with_extension(enum MyEnum value)
196 // 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];
202 // CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable)
203 // 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
212 // CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable)
213 // 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
247 enum MyEnum { A, B, C };
248 static const enum MyEnum D = (enum MyEnum) 32;
249
test_enum_with_extension(enum MyEnum value)250 int 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
261 // CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)
262 // 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
278 // CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable)
279 // 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;
285 // CHECK-NEXT: Preds (1): B2(Unreachable)
286 // 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
test_enum_with_extension_default(enum MyEnum value)313 int 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;
322 }
323
324
325 // CHECK-LABEL: void test_placement_new()
326 // 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
342 extern void* operator new (unsigned long sz, void* v);
343 extern void* operator new[] (unsigned long sz, void* ptr);
344
345 class MyClass {
346 public:
MyClass()347 MyClass() {}
~MyClass()348 ~MyClass() {}
349 };
350
test_placement_new()351 void test_placement_new() {
352 int buffer[16];
353 MyClass* obj = new (buffer) MyClass();
354 }
355
356 // CHECK-LABEL: void test_placement_new_array()
357 // 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
test_placement_new_array()374 void test_placement_new_array() {
375 int buffer[16];
376 MyClass* obj = new (buffer) MyClass[5];
377 }
378
379
380 // CHECK-LABEL: void test_lifetime_extended_temporaries()
381 // CHECK: [B1]
382 struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); };
383 struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; };
384 struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; };
test_lifetime_extended_temporaries()385 void 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
435 // CHECK-LABEL: int *PR18472()
436 // 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
450 extern "C" typedef int *PR18472_t;
451 void *operator new (unsigned long, PR18472_t);
PR18472()452 template <class T> T *PR18472() {
453 return new (((PR18472_t) 0)) T;
454 }
PR18472_helper()455 void PR18472_helper() {
456 PR18472<int>();
457 }
458
459