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
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
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 {};
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
102 void testBuiltinSize() {
103   extern int *dummy();
104   (void)__builtin_object_size(dummy(), 0);
105 }
106 
107 
108 class A {
109 public:
110   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
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
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
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
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 
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
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:
347   MyClass() {}
348   ~MyClass() {}
349 };
350 
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 
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; };
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);
452 template <class T> T *PR18472() {
453   return new (((PR18472_t) 0)) T;
454 }
455 void PR18472_helper() {
456   PR18472<int>();
457 }
458 
459