xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/unreachable-code-path.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc extern void foo(int a);
4*f4a2713aSLionel Sambuc 
5*f4a2713aSLionel Sambuc // The first few tests are non-path specific - we should be able to find them
6*f4a2713aSLionel Sambuc 
test(unsigned a)7*f4a2713aSLionel Sambuc void test(unsigned a) {
8*f4a2713aSLionel Sambuc   switch (a) {
9*f4a2713aSLionel Sambuc     a += 5; // expected-warning{{never executed}}
10*f4a2713aSLionel Sambuc   case 2:
11*f4a2713aSLionel Sambuc     a *= 10;
12*f4a2713aSLionel Sambuc   case 3:
13*f4a2713aSLionel Sambuc     a %= 2;
14*f4a2713aSLionel Sambuc   }
15*f4a2713aSLionel Sambuc   foo(a);
16*f4a2713aSLionel Sambuc }
17*f4a2713aSLionel Sambuc 
test2(unsigned a)18*f4a2713aSLionel Sambuc void test2(unsigned a) {
19*f4a2713aSLionel Sambuc  help:
20*f4a2713aSLionel Sambuc   if (a > 0)
21*f4a2713aSLionel Sambuc     return;
22*f4a2713aSLionel Sambuc   if (a == 0)
23*f4a2713aSLionel Sambuc     return;
24*f4a2713aSLionel Sambuc   foo(a); // expected-warning{{never executed}}
25*f4a2713aSLionel Sambuc   goto help;
26*f4a2713aSLionel Sambuc }
27*f4a2713aSLionel Sambuc 
test3(unsigned a)28*f4a2713aSLionel Sambuc void test3(unsigned a) {
29*f4a2713aSLionel Sambuc   while(1);
30*f4a2713aSLionel Sambuc   if (a > 5) { // expected-warning{{never executed}}
31*f4a2713aSLionel Sambuc     return;
32*f4a2713aSLionel Sambuc   }
33*f4a2713aSLionel Sambuc }
34*f4a2713aSLionel Sambuc 
35*f4a2713aSLionel Sambuc // These next tests are path-sensitive
36*f4a2713aSLionel Sambuc 
test4()37*f4a2713aSLionel Sambuc void test4() {
38*f4a2713aSLionel Sambuc   int a = 5;
39*f4a2713aSLionel Sambuc 
40*f4a2713aSLionel Sambuc   while (a > 1)
41*f4a2713aSLionel Sambuc     a -= 2;
42*f4a2713aSLionel Sambuc 
43*f4a2713aSLionel Sambuc   if (a > 1) {
44*f4a2713aSLionel Sambuc     a = a + 56; // expected-warning{{never executed}}
45*f4a2713aSLionel Sambuc   }
46*f4a2713aSLionel Sambuc 
47*f4a2713aSLionel Sambuc   foo(a);
48*f4a2713aSLionel Sambuc }
49*f4a2713aSLionel Sambuc 
50*f4a2713aSLionel Sambuc extern void bar(char c);
51*f4a2713aSLionel Sambuc 
test5(const char * c)52*f4a2713aSLionel Sambuc void test5(const char *c) {
53*f4a2713aSLionel Sambuc   foo(c[0]);
54*f4a2713aSLionel Sambuc 
55*f4a2713aSLionel Sambuc   if (!c) {
56*f4a2713aSLionel Sambuc     bar(1); // expected-warning{{never executed}}
57*f4a2713aSLionel Sambuc   }
58*f4a2713aSLionel Sambuc }
59*f4a2713aSLionel Sambuc 
60*f4a2713aSLionel Sambuc // These next tests are false positives and should not generate warnings
61*f4a2713aSLionel Sambuc 
test6(const char * c)62*f4a2713aSLionel Sambuc void test6(const char *c) {
63*f4a2713aSLionel Sambuc   if (c) return;
64*f4a2713aSLionel Sambuc   if (!c) return;
65*f4a2713aSLionel Sambuc   __builtin_unreachable(); // no-warning
66*f4a2713aSLionel Sambuc }
67*f4a2713aSLionel Sambuc 
68*f4a2713aSLionel Sambuc // Compile-time constant false positives
69*f4a2713aSLionel Sambuc #define CONSTANT 0
70*f4a2713aSLionel Sambuc enum test_enum { Off, On };
test7()71*f4a2713aSLionel Sambuc void test7() {
72*f4a2713aSLionel Sambuc   if (CONSTANT)
73*f4a2713aSLionel Sambuc     return; // no-warning
74*f4a2713aSLionel Sambuc 
75*f4a2713aSLionel Sambuc   if (sizeof(int))
76*f4a2713aSLionel Sambuc     return; // no-warning
77*f4a2713aSLionel Sambuc 
78*f4a2713aSLionel Sambuc   if (Off)
79*f4a2713aSLionel Sambuc     return; // no-warning
80*f4a2713aSLionel Sambuc }
81*f4a2713aSLionel Sambuc 
test8()82*f4a2713aSLionel Sambuc void test8() {
83*f4a2713aSLionel Sambuc   static unsigned a = 0;
84*f4a2713aSLionel Sambuc 
85*f4a2713aSLionel Sambuc   if (a)
86*f4a2713aSLionel Sambuc     a = 123; // no-warning
87*f4a2713aSLionel Sambuc 
88*f4a2713aSLionel Sambuc   a = 5;
89*f4a2713aSLionel Sambuc }
90*f4a2713aSLionel Sambuc 
91*f4a2713aSLionel Sambuc // Check for bugs where multiple statements are reported
test9(unsigned a)92*f4a2713aSLionel Sambuc void test9(unsigned a) {
93*f4a2713aSLionel Sambuc   switch (a) {
94*f4a2713aSLionel Sambuc     if (a) // expected-warning{{never executed}}
95*f4a2713aSLionel Sambuc       foo(a + 5); // no-warning
96*f4a2713aSLionel Sambuc     else          // no-warning
97*f4a2713aSLionel Sambuc       foo(a);     // no-warning
98*f4a2713aSLionel Sambuc     case 1:
99*f4a2713aSLionel Sambuc     case 2:
100*f4a2713aSLionel Sambuc       break;
101*f4a2713aSLionel Sambuc     default:
102*f4a2713aSLionel Sambuc       break;
103*f4a2713aSLionel Sambuc   }
104*f4a2713aSLionel Sambuc }
105*f4a2713aSLionel Sambuc 
106*f4a2713aSLionel Sambuc // Tests from flow-sensitive version
test10()107*f4a2713aSLionel Sambuc void test10() {
108*f4a2713aSLionel Sambuc   goto c;
109*f4a2713aSLionel Sambuc   d:
110*f4a2713aSLionel Sambuc   goto e; // expected-warning {{never executed}}
111*f4a2713aSLionel Sambuc   c: ;
112*f4a2713aSLionel Sambuc   int i;
113*f4a2713aSLionel Sambuc   return;
114*f4a2713aSLionel Sambuc   goto b; // expected-warning {{never executed}}
115*f4a2713aSLionel Sambuc   goto a; // expected-warning {{never executed}}
116*f4a2713aSLionel Sambuc   b:
117*f4a2713aSLionel Sambuc   i = 1; // no-warning
118*f4a2713aSLionel Sambuc   a:
119*f4a2713aSLionel Sambuc   i = 2;  // no-warning
120*f4a2713aSLionel Sambuc   goto f;
121*f4a2713aSLionel Sambuc   e:
122*f4a2713aSLionel Sambuc   goto d;
123*f4a2713aSLionel Sambuc   f: ;
124*f4a2713aSLionel Sambuc }
125*f4a2713aSLionel Sambuc 
126*f4a2713aSLionel Sambuc // test11: we can actually end up in the default case, even if it is not
127*f4a2713aSLionel Sambuc // obvious: there might be something wrong with the given argument.
128*f4a2713aSLionel Sambuc enum foobar { FOO, BAR };
129*f4a2713aSLionel Sambuc extern void error();
test11(enum foobar fb)130*f4a2713aSLionel Sambuc void test11(enum foobar fb) {
131*f4a2713aSLionel Sambuc   switch (fb) {
132*f4a2713aSLionel Sambuc     case FOO:
133*f4a2713aSLionel Sambuc       break;
134*f4a2713aSLionel Sambuc     case BAR:
135*f4a2713aSLionel Sambuc       break;
136*f4a2713aSLionel Sambuc     default:
137*f4a2713aSLionel Sambuc       error(); // no-warning
138*f4a2713aSLionel Sambuc       return;
139*f4a2713aSLionel Sambuc       error(); // expected-warning {{never executed}}
140*f4a2713aSLionel Sambuc   }
141*f4a2713aSLionel Sambuc }
142*f4a2713aSLionel Sambuc 
inlined(int condition)143*f4a2713aSLionel Sambuc void inlined(int condition) {
144*f4a2713aSLionel Sambuc   if (condition) {
145*f4a2713aSLionel Sambuc     foo(5); // no-warning
146*f4a2713aSLionel Sambuc   } else {
147*f4a2713aSLionel Sambuc     foo(6);
148*f4a2713aSLionel Sambuc   }
149*f4a2713aSLionel Sambuc }
150*f4a2713aSLionel Sambuc 
testInlined()151*f4a2713aSLionel Sambuc void testInlined() {
152*f4a2713aSLionel Sambuc   extern int coin();
153*f4a2713aSLionel Sambuc   int cond = coin();
154*f4a2713aSLionel Sambuc   if (!cond) {
155*f4a2713aSLionel Sambuc     inlined(0);
156*f4a2713aSLionel Sambuc     if (cond) {
157*f4a2713aSLionel Sambuc       foo(5); // expected-warning {{never executed}}
158*f4a2713aSLionel Sambuc     }
159*f4a2713aSLionel Sambuc   }
160*f4a2713aSLionel Sambuc }
161