• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs
2 
3 #include "warn-unreachable.h"
4 
5 int halt() __attribute__((noreturn));
6 int live();
7 int dead();
8 
test1()9 void test1() {
10   goto c;
11   d:
12   goto e;       // expected-warning {{will never be executed}}
13   c: ;
14   int i;
15   return;
16   goto b;        // expected-warning {{will never be executed}}
17   goto a;        // expected-warning {{will never be executed}}
18   b:
19   i = 1;
20   a:
21   i = 2;
22   goto f;
23   e:
24   goto d;
25   f: ;
26 }
27 
test2()28 void test2() {
29   int i;
30   switch (live()) {
31   case 1:
32     halt(),
33       dead();   // expected-warning {{will never be executed}}
34 
35   case 2:
36     live(), halt(),
37       dead();   // expected-warning {{will never be executed}}
38 
39   case 3:
40   live()
41     +           // expected-warning {{will never be executed}}
42     halt();
43   dead();
44 
45   case 4:
46   a4:
47     live(),
48       halt();
49     goto a4;    // expected-warning {{will never be executed}}
50 
51   case 5:
52     goto a5;
53   c5:
54     dead();     // expected-warning {{will never be executed}}
55     goto b5;
56   a5:
57     live(),
58       halt();
59   b5:
60     goto c5;
61 
62   case 6:
63     if (live())
64       goto e6;
65     live(),
66       halt();
67   d6:
68     dead();     // expected-warning {{will never be executed}}
69     goto b6;
70   c6:
71     dead();
72     goto b6;
73   e6:
74     live(),
75       halt();
76   b6:
77     goto c6;
78   case 7:
79     halt()
80       +
81       dead();   // expected-warning {{will never be executed}}
82     -           // expected-warning {{will never be executed}}
83       halt();
84   case 8:
85     i
86       +=        // expected-warning {{will never be executed}}
87       halt();
88   case 9:
89     halt()
90       ?         // expected-warning {{will never be executed}}
91       dead() : dead();
92   case 10:
93     (           // expected-warning {{will never be executed}}
94       float)halt();
95   case 11: {
96     int a[5];
97     live(),
98       a[halt()
99         ];      // expected-warning {{will never be executed}}
100   }
101   }
102 }
103 
104 enum Cases { C1, C2, C3 };
test_enum_cases(enum Cases C)105 int test_enum_cases(enum Cases C) {
106   switch (C) {
107     case C1:
108     case C2:
109     case C3:
110       return 1;
111     default: {
112       int i = 0; // no-warning
113       ++i;
114       return i;
115     }
116   }
117 }
118 
119 // Handle unreachable code triggered by macro expansions.
120 void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
121 
122 #define myassert(e) \
123     (__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
124 
test_assert()125 void test_assert() {
126   myassert(0 && "unreachable");
127   return; // no-warning
128 }
129 
130 // Test case for PR 9774.  Tests that dead code in macros aren't warned about.
131 #define MY_MAX(a,b)     ((a) >= (b) ? (a) : (b))
PR9774(int * s)132 void PR9774(int *s) {
133     for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning
134         s[i] = 0;
135 }
136 
137 // Test case for <rdar://problem/11005770>.  We should treat code guarded
138 // by 'x & 0' and 'x * 0' as unreachable.
139 int calledFun();
test_mul_and_zero(int x)140 void test_mul_and_zero(int x) {
141   if (x & 0) calledFun(); // expected-warning {{will never be executed}}
142   if (0 & x) calledFun(); // expected-warning {{will never be executed}}
143   if (x * 0) calledFun(); // expected-warning {{will never be executed}}
144   if (0 * x) calledFun(); // expected-warning {{will never be executed}}
145 }
146 
147 void raze() __attribute__((noreturn));
148 void warn_here();
149 
test_break_preceded_by_noreturn(int i)150 int test_break_preceded_by_noreturn(int i) {
151   switch (i) {
152     case 1:
153       raze();
154       break; // expected-warning {{'break' will never be executed}}
155     case 2:
156       raze();
157       break; // expected-warning {{'break' will never be executed}}
158       warn_here(); // expected-warning {{will never be executed}}
159     case 3:
160       return 1;
161       break; // expected-warning {{will never be executed}}
162     default:
163       break;
164       break; // expected-warning {{will never be executed}}
165   }
166   return i;
167 }
168 
169 // Don't warn about unreachable 'default' cases, as that is covered
170 // by -Wcovered-switch-default.
171 typedef enum { Value1 = 1 } MyEnum;
unreachable_default(MyEnum e)172 void unreachable_default(MyEnum e) {
173   switch (e) {
174   case Value1:
175     calledFun();
176     break;
177   case 2: // expected-warning {{case value not in enumerated type 'MyEnum'}}
178     calledFun();
179     break;
180   default:
181     calledFun(); // no-warning
182     break;
183   }
184 }
unreachable_in_default(MyEnum e)185 void unreachable_in_default(MyEnum e) {
186   switch (e) {
187   default:
188     raze();
189     calledFun(); // expected-warning {{will never be executed}}
190     break;
191   }
192 }
193 
194 // Don't warn about trivial dead returns.
trivial_dead_return()195 int trivial_dead_return() {
196   raze();
197   return ((0)); // expected-warning {{'return' will never be executed}}
198 }
199 
trivial_dead_return_void()200 void trivial_dead_return_void() {
201   raze();
202   return; // expected-warning {{'return' will never be executed}}
203 }
204 
trivial_dead_return_enum()205 MyEnum trivial_dead_return_enum() {
206   raze();
207   return Value1; // expected-warning {{'return' will never be executed}}
208 }
209 
trivial_dead_return_enum_2(int x)210 MyEnum trivial_dead_return_enum_2(int x) {
211   switch (x) {
212     case 1: return 1;
213     case 2: return 2;
214     case 3: return 3;
215     default: return 4;
216   }
217 
218   return 2; // expected-warning {{will never be executed}}
219 }
220 
trivial_dead_return_cstr()221 const char *trivial_dead_return_cstr() {
222   raze();
223   return ""; // expected-warning {{return' will never be executed}}
224 }
225 
trivial_dead_return_char()226 char trivial_dead_return_char() {
227   raze();
228   return ' '; // expected-warning {{return' will never be executed}}
229 }
230 
nontrivial_dead_return_enum_2(int x)231 MyEnum nontrivial_dead_return_enum_2(int x) {
232   switch (x) {
233     case 1: return 1;
234     case 2: return 2;
235     case 3: return 3;
236     default: return 4;
237   }
238 
239   return calledFun(); // expected-warning {{will never be executed}}
240 }
241 
242 enum X { A, B, C };
243 
covered_switch(enum X x)244 int covered_switch(enum X x) {
245   switch (x) {
246   case A: return 1;
247   case B: return 2;
248   case C: return 3;
249   }
250   return 4; // no-warning
251 }
252 
253 // Test unreachable code depending on configuration values
254 #define CONFIG_CONSTANT 1
test_config_constant(int x)255 int test_config_constant(int x) {
256   if (!CONFIG_CONSTANT) {
257     calledFun(); // no-warning
258     return 1;
259   }
260   if (!1) { // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
261     calledFun(); // expected-warning {{will never be executed}}
262     return 1;
263   }
264   if (sizeof(int) > sizeof(char)) {
265     calledFun(); // no-warning
266     return 1;
267   }
268   if (x > 10)
269     return CONFIG_CONSTANT ? calledFun() : calledFun(); // no-warning
270   else
271     return 1 ? // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
272       calledFun() :
273       calledFun(); // expected-warning {{will never be executed}}
274 }
275 
sizeof_int(int x,int y)276 int sizeof_int(int x, int y) {
277   if (sizeof(long) == sizeof(int))
278     return 1; // no-warning
279   if (sizeof(long) != sizeof(int))
280     return 0; // no-warning
281   if (x && y && sizeof(long) < sizeof(char))
282     return 0; // no-warning
283   return 2; // no-warning
284 }
285 
286 enum MyEnum2 {
287   ME_A = CONFIG_CONSTANT,
288   ME_B = 1
289 };
290 
test_MyEnum()291 int test_MyEnum() {
292   if (!ME_A)
293     return 1; // no-warning
294   if (ME_A)
295     return 2; // no-warning
296   if (ME_B)
297     return 3;
298   if (!ME_B) // expected-warning {{will never be executed}}
299     return 4; // expected-warning {{will never be executed}}
300   return 5;
301 }
302 
303 // Test for idiomatic do..while.
test_do_while(int x)304 int test_do_while(int x) {
305   do {
306     if (x == calledFun())
307       break;
308     ++x;
309     break;
310   }
311   while (0); // no-warning
312   return x;
313 }
314 
test_do_while_nontrivial_cond(int x)315 int test_do_while_nontrivial_cond(int x) {
316   do {
317     if (x == calledFun())
318       break;
319     ++x;
320     break;
321   }
322   while (calledFun()); // expected-warning {{will never be executed}}
323   return x;
324 }
325 
326 // Diagnostic control: -Wunreachable-code-return.
327 
328 #pragma clang diagnostic push
329 #pragma clang diagnostic ignored "-Wunreachable-code-return"
330 
trivial_dead_return_void_SUPPRESSED()331 void trivial_dead_return_void_SUPPRESSED() {
332   raze();
333   return; // no-warning
334 }
335 
trivial_dead_return_enum_SUPPRESSED()336 MyEnum trivial_dead_return_enum_SUPPRESSED() {
337   raze();
338   return Value1; // no-warning
339 }
340 
341 #pragma clang diagnostic pop
342 
343 // Diagnostic control: -Wunreachable-code-break.
344 
345 #pragma clang diagnostic push
346 #pragma clang diagnostic ignored "-Wunreachable-code-break"
347 
test_break_preceded_by_noreturn_SUPPRESSED(int i)348 int test_break_preceded_by_noreturn_SUPPRESSED(int i) {
349   switch (i) {
350     case 1:
351       raze();
352       break; // no-warning
353     case 2:
354       raze();
355       break; // no-warning
356       warn_here(); // expected-warning {{will never be executed}}
357     case 3:
358       return 1;
359       break; // no-warning
360     default:
361       break;
362       break; // no-warning
363   }
364   return i;
365 }
366 
367 #pragma clang diagnostic pop
368 
369 // Test "silencing" with parentheses.
test_with_paren_silencing(int x)370 void test_with_paren_silencing(int x) {
371   if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
372   if ((0)) calledFun(); // no-warning
373 
374   if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
375     calledFun();
376   else
377     calledFun(); // expected-warning {{will never be executed}}
378 
379   if ((1))
380     calledFun();
381   else
382     calledFun(); // no-warning
383 
384   if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
385     calledFun(); // expected-warning {{code will never be executed}}
386   else
387     calledFun();
388 
389   if ((!1))
390     calledFun(); // no-warning
391   else
392     calledFun();
393 
394   if (!(1))
395     calledFun(); // no-warning
396   else
397     calledFun();
398 }
399