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