1// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -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
15void 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
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}
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
85enum EmptyE {};
86void 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
102void testBuiltinSize() {
103  extern int *dummy();
104  (void)__builtin_object_size(dummy(), 0);
105}
106
107
108class A {
109public:
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
130void 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
152void test_deleteArraydtor() {
153  A *a = new A[5];
154  delete[] a;
155}
156
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
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
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
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
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;
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
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
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
374void test_placement_new_array() {
375  int buffer[16];
376  MyClass* obj = new (buffer) MyClass[5];
377}
378
379
380// CHECK-LABEL: int *PR18472()
381// CHECK: [B2 (ENTRY)]
382// CHECK-NEXT:   Succs (1): B1
383// CHECK: [B1]
384// CHECK-NEXT:   1: 0
385// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)
386// CHECK-NEXT:   3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)
387// CHECK-NEXT:   4: CFGNewAllocator(int *)
388// CHECK-NEXT:   5: new (([B1.3])) int
389// CHECK-NEXT:   6: return [B1.5];
390// CHECK-NEXT:   Preds (1): B2
391// CHECK-NEXT:   Succs (1): B0
392// CHECK: [B0 (EXIT)]
393// CHECK-NEXT:   Preds (1): B1
394
395extern "C" typedef int *PR18472_t;
396void *operator new (unsigned long, PR18472_t);
397template <class T> T *PR18472() {
398  return new (((PR18472_t) 0)) T;
399}
400void PR18472_helper() {
401  PR18472<int>();
402}
403
404