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
5
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.
14
15 // CHECK-LABEL: void checkWrap(int i)
16 // CHECK: ENTRY
17 // CHECK-NEXT: Succs (1): B1
18 // CHECK: [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
21 // CHECK: B20 B21 B0
22 // CHECK: [B0 (EXIT)]
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
checkWrap(int i)26 void checkWrap(int i) {
27 switch(i) {
28 case 0: break;
29 case 1: break;
30 case 2: break;
31 case 3: break;
32 case 4: break;
33 case 5: break;
34 case 6: break;
35 case 7: break;
36 case 8: break;
37 case 9: break;
38 case 10: break;
39 case 11: break;
40 case 12: break;
41 case 13: break;
42 case 14: break;
43 case 15: break;
44 case 16: break;
45 case 17: break;
46 case 18: break;
47 case 19: break;
48 }
49 }
50
51 // CHECK-LABEL: void checkDeclStmts()
52 // CHECK: ENTRY
53 // CHECK-NEXT: Succs (1): B1
54 // CHECK: [B1]
55 // CHECK-NEXT: 1: int i;
56 // CHECK-NEXT: 2: int j;
57 // CHECK-NEXT: 3: 1
58 // CHECK-NEXT: 4: int k = 1;
59 // CHECK-NEXT: 5: int l;
60 // CHECK-NEXT: 6: 2
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
checkDeclStmts()73 void checkDeclStmts() {
74 int i, j;
75 int k = 1, l, m = 2;
76
77 struct standalone { int x, y; };
78 struct standalone myStandalone;
79
80 struct { int x, y; } myAnon;
81
82 struct named { int x, y; } myNamed;
83
84 static_assert(1, "abc");
85 }
86
87
88 // CHECK-LABEL: void checkGCCAsmRValueOutput()
89 // CHECK: [B2 (ENTRY)]
90 // CHECK-NEXT: Succs (1): B1
91 // CHECK: [B1]
92 // CHECK-NEXT: 1: int arg
93 // CHECK-NEXT: 2: arg
94 // CHECK-NEXT: 3: (int)[B1.2] (CStyleCastExpr, NoOp, int)
95 // CHECK-NEXT: 4: asm ("" : "=r" ([B1.3]));
96 // CHECK-NEXT: 5: arg
97 // CHECK-NEXT: 6: asm ("" : "=r" ([B1.5]));
checkGCCAsmRValueOutput()98 void checkGCCAsmRValueOutput() {
99 int arg;
100 __asm__("" : "=r"((int)arg)); // rvalue output operand
101 __asm__("" : "=r"(arg)); // lvalue output operand
102 }
103
104
105 // CHECK-LABEL: void F(EmptyE e)
106 // CHECK: ENTRY
107 // CHECK-NEXT: Succs (1): B1
108 // CHECK: [B1]
109 // CHECK-NEXT: 1: e
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
117 enum EmptyE {};
F(EmptyE e)118 void F(EmptyE e) {
119 switch (e) {}
120 }
121
122 // CHECK-LABEL: void testBuiltinSize()
123 // CHECK: ENTRY
124 // CHECK-NEXT: Succs (1): B1
125 // CHECK: [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
testBuiltinSize()134 void testBuiltinSize() {
135 extern int *dummy();
136 (void)__builtin_object_size(dummy(), 0);
137 }
138
139
140 class A {
141 public:
A()142 A() {}
~A()143 ~A() {}
144 };
145
146 // CHECK-LABEL: void test_deletedtor()
147 // CHECK: [B2 (ENTRY)]
148 // CHECK-NEXT: Succs (1): B1
149 // CHECK: [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();
155 // CHECK-NEXT: 5: 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
test_deletedtor()163 void test_deletedtor() {
164 A *a = new A();
165 delete a;
166 }
167
168 // CHECK-LABEL: void test_deleteArraydtor()
169 // CHECK: [B2 (ENTRY)]
170 // CHECK-NEXT: Succs (1): B1
171 // CHECK: [B1]
172 // CHECK-NEXT: 1: 5
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];
178 // CHECK-NEXT: 6: a
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
test_deleteArraydtor()186 void test_deleteArraydtor() {
187 A *a = new A[5];
188 delete[] a;
189 }
190
191
192 namespace NoReturnSingleSuccessor {
193 struct A {
194 A();
195 ~A();
196 };
197
198 struct B : public A {
199 B();
200 ~B() __attribute__((noreturn));
201 };
202
203 // CHECK-LABEL: int test1(int *x)
204 // CHECK: 1: 1
205 // CHECK-NEXT: 2: return
206 // CHECK-NEXT: ~NoReturnSingleSuccessor::B() (Implicit destructor)
207 // CHECK-NEXT: Preds (1)
208 // CHECK-NEXT: Succs (1): B0
test1(int * x)209 int test1(int *x) {
210 B b;
211 if (x)
212 return 1;
213 }
214
215 // CHECK-LABEL: int test2(int *x)
216 // CHECK: 1: 1
217 // CHECK-NEXT: 2: return
218 // CHECK-NEXT: destructor
219 // CHECK-NEXT: Preds (1)
220 // CHECK-NEXT: Succs (1): B0
test2(int * x)221 int test2(int *x) {
222 const A& a = B();
223 if (x)
224 return 1;
225 }
226 }
227
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
232 // CHECK: [B1]
233 // CHECK-NEXT: 1: x
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
238 // CHECK: [B2]
239 // CHECK-NEXT: 1: 0
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)
247 // CHECK: [B3]
248 // CHECK-NEXT: case D:
249 // CHECK-NEXT: 1: 4
250 // CHECK-NEXT: 2: x
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
255 // CHECK: [B4]
256 // CHECK-NEXT: case C:
257 // CHECK-NEXT: 1: 3
258 // CHECK-NEXT: 2: x
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
263 // CHECK: [B5]
264 // CHECK-NEXT: case B:
265 // CHECK-NEXT: 1: 2
266 // CHECK-NEXT: 2: x
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
271 // CHECK: [B6]
272 // CHECK-NEXT: case A:
273 // CHECK-NEXT: 1: 1
274 // CHECK-NEXT: 2: x
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;
283
test_enum_with_extension(enum MyEnum value)284 int test_enum_with_extension(enum MyEnum value) {
285 int x = 0;
286 switch (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;
291 }
292 return x;
293 }
294
295 // CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)
296 // CHECK: [B7 (ENTRY)]
297 // CHECK-NEXT: Succs (1): B2
298 // CHECK: [B1]
299 // CHECK-NEXT: 1: x
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
304 // CHECK: [B2]
305 // CHECK-NEXT: 1: 0
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)
313 // CHECK: [B3]
314 // CHECK-NEXT: default:
315 // CHECK-NEXT: 1: 4
316 // CHECK-NEXT: 2: x
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
321 // CHECK: [B4]
322 // CHECK-NEXT: case C:
323 // CHECK-NEXT: 1: 3
324 // CHECK-NEXT: 2: x
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
329 // CHECK: [B5]
330 // CHECK-NEXT: case B:
331 // CHECK-NEXT: 1: 2
332 // CHECK-NEXT: 2: x
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
337 // CHECK: [B6]
338 // CHECK-NEXT: case A:
339 // CHECK-NEXT: 1: 1
340 // CHECK-NEXT: 2: x
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
test_enum_with_extension_default(enum MyEnum value)347 int test_enum_with_extension_default(enum MyEnum value) {
348 int x = 0;
349 switch (value) {
350 case A: x = 1; break;
351 case B: x = 2; break;
352 case C: x = 3; break;
353 default: x = 4; break;
354 }
355 return x;
356 }
357
358
359 // CHECK-LABEL: void test_placement_new()
360 // CHECK: [B2 (ENTRY)]
361 // CHECK-NEXT: Succs (1): B1
362 // CHECK: [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
376
377 extern void* operator new (unsigned long sz, void* v);
378 extern void* operator new[] (unsigned long sz, void* ptr);
379
380 class MyClass {
381 public:
MyClass()382 MyClass() {}
~MyClass()383 ~MyClass() {}
384 };
385
test_placement_new()386 void test_placement_new() {
387 int buffer[16];
388 MyClass* obj = new (buffer) MyClass();
389 }
390
391 // CHECK-LABEL: void test_placement_new_array()
392 // CHECK: [B2 (ENTRY)]
393 // CHECK-NEXT: Succs (1): B1
394 // CHECK: [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 *)
399 // CHECK-NEXT: 5: 5
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
409
test_placement_new_array()410 void test_placement_new_array() {
411 int buffer[16];
412 MyClass* obj = new (buffer) MyClass[5];
413 }
414
415
416 // CHECK-LABEL: void test_lifetime_extended_temporaries()
417 // CHECK: [B1]
418 struct LifetimeExtend { LifetimeExtend(int); ~LifetimeExtend(); };
419 struct Aggregate { const LifetimeExtend a; const LifetimeExtend b; };
420 struct AggregateRef { const LifetimeExtend &a; const LifetimeExtend &b; };
test_lifetime_extended_temporaries()421 void test_lifetime_extended_temporaries() {
422 // CHECK: LifetimeExtend(1);
423 // CHECK-NEXT: : 1
424 // CHECK-NEXT: ~LifetimeExtend()
425 // CHECK-NOT: ~LifetimeExtend()
426 {
427 const LifetimeExtend &l = LifetimeExtend(1);
428 1;
429 }
430 // CHECK: LifetimeExtend(2)
431 // CHECK-NEXT: ~LifetimeExtend()
432 // CHECK-NEXT: : 2
433 // CHECK-NOT: ~LifetimeExtend()
434 {
435 // No life-time extension.
436 const int &l = (LifetimeExtend(2), 2);
437 2;
438 }
439 // CHECK: LifetimeExtend(3)
440 // CHECK-NEXT: : 3
441 // CHECK-NEXT: ~LifetimeExtend()
442 // CHECK-NOT: ~LifetimeExtend()
443 {
444 // The last one is lifetime extended.
445 const LifetimeExtend &l = (3, LifetimeExtend(3));
446 3;
447 }
448 // CHECK: LifetimeExtend(4)
449 // CHECK-NEXT: ~LifetimeExtend()
450 // CHECK-NEXT: ~LifetimeExtend()
451 // CHECK-NEXT: : 4
452 // CHECK-NOT: ~LifetimeExtend()
453 {
454 Aggregate a{LifetimeExtend(4), LifetimeExtend(4)};
455 4;
456 }
457 // CHECK: LifetimeExtend(5)
458 // CHECK-NEXT: : 5
459 // FIXME: We want to emit the destructors of the lifetime
460 // extended variables here.
461 // CHECK-NOT: ~LifetimeExtend()
462 {
463 AggregateRef a{LifetimeExtend(5), LifetimeExtend(5)};
464 5;
465 }
466 // FIXME: Add tests for lifetime extension via subobject
467 // references (LifetimeExtend().some_member).
468 }
469
470
471 // FIXME: The destructor for 'a' shouldn't be there because it's deleted
472 // in the union.
473 // CHECK-LABEL: void foo()
474 // CHECK: [B2 (ENTRY)]
475 // CHECK-NEXT: Succs (1): B1
476 // CHECK: [B1]
477 // WARNINGS-NEXT: 1: (CXXConstructExpr, struct pr37688_deleted_union_destructor::A)
478 // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], struct pr37688_deleted_union_destructor::A)
479 // CHECK-NEXT: 2: pr37688_deleted_union_destructor::A a;
480 // CHECK-NEXT: 3: [B1.2].~pr37688_deleted_union_destructor::A() (Implicit destructor)
481 // CHECK-NEXT: Preds (1): B2
482 // CHECK-NEXT: Succs (1): B0
483 // CHECK: [B0 (EXIT)]
484 // CHECK-NEXT: Preds (1): B1
485
486 namespace pr37688_deleted_union_destructor {
487 struct S { ~S(); };
488 struct A {
~Apr37688_deleted_union_destructor::A489 ~A() noexcept {}
490 union {
491 struct {
492 S s;
493 } ss;
494 };
495 };
foo()496 void foo() {
497 A a;
498 }
499 } // end namespace pr37688_deleted_union_destructor
500
501
502 namespace return_statement_expression {
503 int unknown();
504
505 // CHECK-LABEL: int foo()
506 // CHECK: [B6 (ENTRY)]
507 // CHECK-NEXT: Succs (1): B5
508 // CHECK: [B1]
509 // CHECK-NEXT: 1: 0
510 // CHECK-NEXT: 2: return [B1.1];
511 // CHECK-NEXT: Preds (1): B5
512 // CHECK-NEXT: Succs (1): B0
513 // CHECK: [B2]
514 // CHECK-NEXT: 1: 0
515 // CHECK-NEXT: 2: ({ ... ; [B2.1] })
516 // CHECK-NEXT: 3: return [B2.2];
517 // CHECK-NEXT: Preds (1): B4
518 // CHECK-NEXT: Succs (1): B0
519 // FIXME: Why do we have [B3] at all?
520 // CHECK: [B3]
521 // CHECK-NEXT: Succs (1): B4
522 // CHECK: [B4]
523 // CHECK-NEXT: 1: 0
524 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, IntegralToBoolean, _Bool)
525 // CHECK-NEXT: T: while [B4.2]
526 // CHECK-NEXT: Preds (2): B3 B5
527 // CHECK-NEXT: Succs (2): NULL B2
528 // CHECK: [B5]
529 // CHECK-NEXT: 1: unknown
530 // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void))
531 // CHECK-NEXT: 3: [B5.2]()
532 // CHECK-NEXT: 4: [B5.3] (ImplicitCastExpr, IntegralToBoolean, _Bool)
533 // CHECK-NEXT: T: if [B5.4]
534 // CHECK-NEXT: Preds (1): B6
535 // CHECK-NEXT: Succs (2): B4 B1
536 // CHECK: [B0 (EXIT)]
537 // CHECK-NEXT: Preds (2): B1 B2
foo()538 int foo() {
539 if (unknown())
540 return ({
541 while (0)
542 ;
543 0;
544 });
545 else
546 return 0;
547 }
548 } // namespace statement_expression_in_return
549
550 // CHECK-LABEL: int overlap_compare(int x)
551 // CHECK: [B2]
552 // CHECK-NEXT: 1: 1
553 // CHECK-NEXT: 2: return [B2.1];
554 // CHECK-NEXT: Preds (1): B3(Unreachable)
555 // CHECK-NEXT: Succs (1): B0
556 // CHECK: [B3]
557 // CHECK-NEXT: 1: x
558 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, LValueToRValue, int)
559 // CHECK-NEXT: 3: 5
560 // CHECK-NEXT: 4: [B3.2] > [B3.3]
561 // CHECK-NEXT: T: if [B4.5] && [B3.4]
562 // CHECK-NEXT: Preds (1): B4
563 // CHECK-NEXT: Succs (2): B2(Unreachable) B1
overlap_compare(int x)564 int overlap_compare(int x) {
565 if (x == -1 && x > 5)
566 return 1;
567
568 return 2;
569 }
570
571 // CHECK-LABEL: template<> int *PR18472<int>()
572 // CHECK: [B2 (ENTRY)]
573 // CHECK-NEXT: Succs (1): B1
574 // CHECK: [B1]
575 // CHECK-NEXT: 1: 0
576 // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)
577 // CHECK-NEXT: 3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)
578 // CHECK-NEXT: 4: CFGNewAllocator(int *)
579 // CHECK-NEXT: 5: new (([B1.3])) int
580 // CHECK-NEXT: 6: return [B1.5];
581 // CHECK-NEXT: Preds (1): B2
582 // CHECK-NEXT: Succs (1): B0
583 // CHECK: [B0 (EXIT)]
584 // CHECK-NEXT: Preds (1): B1
585
586 extern "C" typedef int *PR18472_t;
587 void *operator new (unsigned long, PR18472_t);
PR18472()588 template <class T> T *PR18472() {
589 return new (((PR18472_t) 0)) T;
590 }
PR18472_helper()591 void PR18472_helper() {
592 PR18472<int>();
593 }
594