1 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -fheinous-gnu-extensions -std=c++11 -analyzer-config cfg-rich-constructors=false %s > %t 2>&1
2 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,WARNINGS %s
3 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -fheinous-gnu-extensions -std=c++11 -analyzer-config cfg-rich-constructors=true %s > %t 2>&1
4 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,ANALYZER %s
6 // This file tests how we construct two different flavors of the Clang CFG -
7 // the CFG used by the Sema analysis-based warnings and the CFG used by the
8 // static analyzer. The difference in the behavior is checked via FileCheck
9 // prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer
10 // flags, no new run lines should be added - just these flags would go to the
11 // respective line depending on where is it turned on and where is it turned
12 // off. Feel free to add tests that test only one of the CFG flavors if you're
13 // not sure how the other flavor is supposed to work in your case.
15 // CHECK-LABEL: void checkWrap(int i)
17 // CHECK-NEXT: Succs (1): B1
19 // CHECK: Succs (21): B2 B3 B4 B5 B6 B7 B8 B9
20 // CHECK: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19
23 // CHECK-NEXT: Preds (21): B2 B3 B4 B5 B6 B7 B8 B9
24 // CHECK-NEXT: B10 B11 B12 B13 B14 B15 B16 B17 B18 B19
25 // CHECK-NEXT: B20 B21 B1
26 void checkWrap(int i) {
51 // CHECK-LABEL: void checkDeclStmts()
53 // CHECK-NEXT: Succs (1): B1
55 // CHECK-NEXT: 1: int i;
56 // CHECK-NEXT: 2: int j;
58 // CHECK-NEXT: 4: int k = 1;
59 // CHECK-NEXT: 5: int l;
61 // CHECK-NEXT: 7: int m = 2;
62 // WARNINGS-NEXT: (CXXConstructExpr, struct standalone)
63 // ANALYZER-NEXT: (CXXConstructExpr, [B1.9], struct standalone)
64 // CHECK-NEXT: 9: struct standalone myStandalone;
65 // WARNINGS-NEXT: (CXXConstructExpr, struct (anonymous struct at {{.*}}))
66 // ANALYZER-NEXT: (CXXConstructExpr, [B1.11], struct (anonymous struct at {{.*}}))
67 // CHECK-NEXT: 11: struct (anonymous struct at {{.*}}) myAnon;
68 // WARNINGS-NEXT: (CXXConstructExpr, struct named)
69 // ANALYZER-NEXT: (CXXConstructExpr, [B1.13], struct named)
70 // CHECK-NEXT: 13: struct named myNamed;
71 // CHECK-NEXT: Preds (1): B2
72 // CHECK-NEXT: Succs (1): B0
73 void checkDeclStmts() {
77 struct standalone { int x, y; };
78 struct standalone myStandalone;
80 struct { int x, y; } myAnon;
82 struct named { int x, y; } myNamed;
84 static_assert(1, "abc");
88 // CHECK-LABEL: void checkGCCAsmRValueOutput()
89 // CHECK: [B2 (ENTRY)]
90 // CHECK-NEXT: Succs (1): B1
92 // CHECK-NEXT: 1: int arg
94 // CHECK-NEXT: 3: (int)[B1.2] (CStyleCastExpr, NoOp, int)
95 // CHECK-NEXT: 4: asm ("" : "=r" ([B1.3]));
97 // CHECK-NEXT: 6: asm ("" : "=r" ([B1.5]));
98 void checkGCCAsmRValueOutput() {
100 __asm__("" : "=r"((int)arg)); // rvalue output operand
101 __asm__("" : "=r"(arg)); // lvalue output operand
105 // CHECK-LABEL: void F(EmptyE e)
107 // CHECK-NEXT: Succs (1): B1
110 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, enum EmptyE)
111 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, IntegralCast, int)
112 // CHECK-NEXT: T: switch [B1.3]
113 // CHECK-NEXT: Preds (1): B2
114 // CHECK-NEXT: Succs (1): B0
115 // CHECK: [B0 (EXIT)]
116 // CHECK-NEXT: Preds (1): B1
122 // CHECK-LABEL: void testBuiltinSize()
124 // CHECK-NEXT: Succs (1): B1
126 // CHECK-NEXT: 1: __builtin_object_size
127 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, BuiltinFnToFnPtr, unsigned long (*)(const void *, int) noexcept)
128 // CHECK-NEXT: 3: [B1.2](dummy(), 0)
129 // CHECK-NEXT: 4: (void)[B1.3] (CStyleCastExpr, ToVoid, void)
130 // CHECK-NEXT: Preds (1): B2
131 // CHECK-NEXT: Succs (1): B0
132 // CHECK: [B0 (EXIT)]
133 // CHECK-NEXT: Preds (1): B1
134 void testBuiltinSize() {
136 (void)__builtin_object_size(dummy(), 0);
146 // CHECK-LABEL: void test_deletedtor()
147 // CHECK: [B2 (ENTRY)]
148 // CHECK-NEXT: Succs (1): B1
150 // CHECK-NEXT: 1: CFGNewAllocator(A *)
151 // WARNINGS-NEXT: 2: (CXXConstructExpr, class A)
152 // ANALYZER-NEXT: 2: (CXXConstructExpr, [B1.3], class A)
153 // CHECK-NEXT: 3: new A([B1.2])
154 // CHECK-NEXT: 4: A *a = new A();
156 // CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *)
157 // CHECK-NEXT: 7: [B1.6]->~A() (Implicit destructor)
158 // CHECK-NEXT: 8: delete [B1.6]
159 // CHECK-NEXT: Preds (1): B2
160 // CHECK-NEXT: Succs (1): B0
161 // CHECK: [B0 (EXIT)]
162 // CHECK-NEXT: Preds (1): B1
163 void test_deletedtor() {
168 // CHECK-LABEL: void test_deleteArraydtor()
169 // CHECK: [B2 (ENTRY)]
170 // CHECK-NEXT: Succs (1): B1
173 // CHECK-NEXT: 2: CFGNewAllocator(A *)
174 // WARNINGS-NEXT: 3: (CXXConstructExpr, class A [5])
175 // ANALYZER-NEXT: 3: (CXXConstructExpr, [B1.4], class A [5])
176 // CHECK-NEXT: 4: new A {{\[\[}}B1.1]]
177 // CHECK-NEXT: 5: A *a = new A [5];
179 // CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, class A *)
180 // CHECK-NEXT: 8: [B1.7]->~A() (Implicit destructor)
181 // CHECK-NEXT: 9: delete [] [B1.7]
182 // CHECK-NEXT: Preds (1): B2
183 // CHECK-NEXT: Succs (1): B0
184 // CHECK: [B0 (EXIT)]
185 // CHECK-NEXT: Preds (1): B1
186 void test_deleteArraydtor() {
192 namespace NoReturnSingleSuccessor {
198 struct B : public A {
200 ~B() __attribute__((noreturn));
203 // CHECK-LABEL: int test1(int *x)
205 // CHECK-NEXT: 2: return
206 // CHECK-NEXT: ~B() (Implicit destructor)
207 // CHECK-NEXT: Preds (1)
208 // CHECK-NEXT: Succs (1): B0
215 // CHECK-LABEL: int test2(int *x)
217 // CHECK-NEXT: 2: return
218 // CHECK-NEXT: destructor
219 // CHECK-NEXT: Preds (1)
220 // CHECK-NEXT: Succs (1): B0
228 // Test CFG support for "extending" an enum.
229 // CHECK-LABEL: int test_enum_with_extension(enum MyEnum value)
230 // CHECK: [B7 (ENTRY)]
231 // CHECK-NEXT: Succs (1): B2
234 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
235 // CHECK-NEXT: 3: return [B1.2];
236 // CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable)
237 // CHECK-NEXT: Succs (1): B0
240 // CHECK-NEXT: 2: int x = 0;
241 // CHECK-NEXT: 3: value
242 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)
243 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int)
244 // CHECK-NEXT: T: switch [B2.5]
245 // CHECK-NEXT: Preds (1): B7
246 // CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable)
248 // CHECK-NEXT: case D:
251 // CHECK-NEXT: 3: [B3.2] = [B3.1]
252 // CHECK-NEXT: T: break;
253 // CHECK-NEXT: Preds (1): B2
254 // CHECK-NEXT: Succs (1): B1
256 // CHECK-NEXT: case C:
259 // CHECK-NEXT: 3: [B4.2] = [B4.1]
260 // CHECK-NEXT: T: break;
261 // CHECK-NEXT: Preds (1): B2
262 // CHECK-NEXT: Succs (1): B1
264 // CHECK-NEXT: case B:
267 // CHECK-NEXT: 3: [B5.2] = [B5.1]
268 // CHECK-NEXT: T: break;
269 // CHECK-NEXT: Preds (1): B2
270 // CHECK-NEXT: Succs (1): B1
272 // CHECK-NEXT: case A:
275 // CHECK-NEXT: 3: [B6.2] = [B6.1]
276 // CHECK-NEXT: T: break;
277 // CHECK-NEXT: Preds (1): B2
278 // CHECK-NEXT: Succs (1): B1
279 // CHECK: [B0 (EXIT)]
280 // CHECK-NEXT: Preds (1): B1
281 enum MyEnum { A, B, C };
282 static const enum MyEnum D = (enum MyEnum) 32;
284 int test_enum_with_extension(enum MyEnum value) {
287 case A: x = 1; break;
288 case B: x = 2; break;
289 case C: x = 3; break;
290 case D: x = 4; break;
295 // CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)
296 // CHECK: [B7 (ENTRY)]
297 // CHECK-NEXT: Succs (1): B2
300 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
301 // CHECK-NEXT: 3: return [B1.2];
302 // CHECK-NEXT: Preds (4): B3 B4 B5 B6
303 // CHECK-NEXT: Succs (1): B0
306 // CHECK-NEXT: 2: int x = 0;
307 // CHECK-NEXT: 3: value
308 // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)
309 // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int)
310 // CHECK-NEXT: T: switch [B2.5]
311 // CHECK-NEXT: Preds (1): B7
312 // CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable)
314 // CHECK-NEXT: default:
317 // CHECK-NEXT: 3: [B3.2] = [B3.1]
318 // CHECK-NEXT: T: break;
319 // CHECK-NEXT: Preds (1): B2(Unreachable)
320 // CHECK-NEXT: Succs (1): B1
322 // CHECK-NEXT: case C:
325 // CHECK-NEXT: 3: [B4.2] = [B4.1]
326 // CHECK-NEXT: T: break;
327 // CHECK-NEXT: Preds (1): B2
328 // CHECK-NEXT: Succs (1): B1
330 // CHECK-NEXT: case B:
333 // CHECK-NEXT: 3: [B5.2] = [B5.1]
334 // CHECK-NEXT: T: break;
335 // CHECK-NEXT: Preds (1): B2
336 // CHECK-NEXT: Succs (1): B1
338 // CHECK-NEXT: case A:
341 // CHECK-NEXT: 3: [B6.2] = [B6.1]
342 // CHECK-NEXT: T: break;
343 // CHECK-NEXT: Preds (1): B2
344 // CHECK-NEXT: Succs (1): B1
345 // CHECK: [B0 (EXIT)]
346 // CHECK-NEXT: Preds (1): B1
347 int test_enum_with_extension_default(enum MyEnum value) {
350 case A: x = 1; break;
351 case B: x = 2; break;
352 case C: x = 3; break;
353 default: x = 4; break;
359 // CHECK-LABEL: void test_placement_new()
360 // CHECK: [B2 (ENTRY)]
361 // CHECK-NEXT: Succs (1): B1
363 // CHECK-NEXT: 1: int buffer[16];
364 // CHECK-NEXT: 2: buffer
365 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
366 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)
367 // CHECK-NEXT: 5: CFGNewAllocator(MyClass *)
368 // WARNINGS-NEXT: 6: (CXXConstructExpr, class MyClass)
369 // ANALYZER-NEXT: 6: (CXXConstructExpr, [B1.7], class MyClass)
370 // CHECK-NEXT: 7: new ([B1.4]) MyClass([B1.6])
371 // CHECK-NEXT: 8: MyClass *obj = new (buffer) MyClass();
372 // CHECK-NEXT: Preds (1): B2
373 // CHECK-NEXT: Succs (1): B0
374 // CHECK: [B0 (EXIT)]
375 // CHECK-NEXT: Preds (1): B1
377 extern void* operator new (unsigned long sz, void* v);
378 extern void* operator new[] (unsigned long sz, void* ptr);
386 void test_placement_new() {
388 MyClass* obj = new (buffer) MyClass();
391 // CHECK-LABEL: void test_placement_new_array()
392 // CHECK: [B2 (ENTRY)]
393 // CHECK-NEXT: Succs (1): B1
395 // CHECK-NEXT: 1: int buffer[16];
396 // CHECK-NEXT: 2: buffer
397 // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
398 // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)
400 // CHECK-NEXT: 6: CFGNewAllocator(MyClass *)
401 // WARNINGS-NEXT: 7: (CXXConstructExpr, class MyClass [5])
402 // ANALYZER-NEXT: 7: (CXXConstructExpr, [B1.8], class MyClass [5])
403 // CHECK-NEXT: 8: new ([B1.4]) MyClass {{\[\[}}B1.5]]
404 // CHECK-NEXT: 9: MyClass *obj = new (buffer) MyClass [5];
405 // CHECK-NEXT: Preds (1): B2
406 // CHECK-NEXT: Succs (1): B0
407 // CHECK: [B0 (EXIT)]
408 // CHECK-NEXT: Preds (1): B1
410 void test_placement_new_array() {
412 MyClass* obj = new (buffer) MyClass[5];
416 // CHECK-LABEL: void test_lifetime_extended_temporaries()
418 struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); };
419 struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; };
420 struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; };
421 void test_lifetime_extended_temporaries() {
422 // CHECK: LifetimeExtend(1);
424 // CHECK-NEXT: ~LifetimeExtend()
425 // CHECK-NOT: ~LifetimeExtend()
427 const LifetimeExtend &l = LifetimeExtend(1);
430 // CHECK: LifetimeExtend(2)
431 // CHECK-NEXT: ~LifetimeExtend()
433 // CHECK-NOT: ~LifetimeExtend()
435 // No life-time extension.
436 const int &l = (LifetimeExtend(2), 2);
439 // CHECK: LifetimeExtend(3)
441 // CHECK-NEXT: ~LifetimeExtend()
442 // CHECK-NOT: ~LifetimeExtend()
444 // The last one is lifetime extended.
445 const LifetimeExtend &l = (3, LifetimeExtend(3));
448 // CHECK: LifetimeExtend(4)
449 // CHECK-NEXT: ~LifetimeExtend()
450 // CHECK-NEXT: ~LifetimeExtend()
452 // CHECK-NOT: ~LifetimeExtend()
454 Aggregate a{LifetimeExtend(4), LifetimeExtend(4)};
457 // CHECK: LifetimeExtend(5)
459 // FIXME: We want to emit the destructors of the lifetime
460 // extended variables here.
461 // CHECK-NOT: ~LifetimeExtend()
463 AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)};
466 // FIXME: Add tests for lifetime extension via subobject
467 // references (LifetimeExtend().some_member).
471 // CHECK-LABEL: template<> int *PR18472<int>()
472 // CHECK: [B2 (ENTRY)]
473 // CHECK-NEXT: Succs (1): B1
476 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)
477 // CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)
478 // CHECK-NEXT: 4: CFGNewAllocator(int *)
479 // CHECK-NEXT: 5: new (([B1.3])) int
480 // CHECK-NEXT: 6: return [B1.5];
481 // CHECK-NEXT: Preds (1): B2
482 // CHECK-NEXT: Succs (1): B0
483 // CHECK: [B0 (EXIT)]
484 // CHECK-NEXT: Preds (1): B1
486 extern "C" typedef int *PR18472_t;
487 void *operator new (unsigned long, PR18472_t);
488 template <class T> T *PR18472() {
489 return new (((PR18472_t) 0)) T;
491 void PR18472_helper() {