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