xref: /llvm-project/clang/test/Sema/warn-unreachable.c (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs %s
2 // RUN: %clang_cc1 -fsyntax-only -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -fdiagnostics-parseable-fixits -I %S/Inputs %s 2>&1 | FileCheck %s
3 
4 #include "warn-unreachable.h"
5 
6 int halt(void) __attribute__((noreturn));
7 int live(void);
8 int dead(void);
9 
test1(void)10 void test1(void) {
11   goto c;
12   d:
13   goto e;       // expected-warning {{will never be executed}}
14   c: ;
15   int i;
16   return;
17   goto b;        // expected-warning {{will never be executed}}
18   goto a;        // expected-warning {{will never be executed}}
19   b:
20   i = 1;
21   a:
22   i = 2;
23   goto f;
24   e:
25   goto d;
26   f: ;
27 }
28 
test2(void)29 void test2(void) {
30   int i;
31   switch (live()) {
32   case 1:
33     halt(),
34       dead();   // expected-warning {{will never be executed}}
35 
36   case 2:
37     live(), halt(),
38       dead();   // expected-warning {{will never be executed}}
39 
40   case 3:
41   live()
42     +           // expected-warning {{will never be executed}}
43     halt();
44   dead();
45 
46   case 4:
47   a4:
48     live(),
49       halt();
50     goto a4;    // expected-warning {{will never be executed}}
51 
52   case 5:
53     goto a5;
54   c5:
55     dead();     // expected-warning {{will never be executed}}
56     goto b5;
57   a5:
58     live(),
59       halt();
60   b5:
61     goto c5;
62 
63   case 6:
64     if (live())
65       goto e6;
66     live(),
67       halt();
68   d6:
69     dead();     // expected-warning {{will never be executed}}
70     goto b6;
71   c6:
72     dead();
73     goto b6;
74   e6:
75     live(),
76       halt();
77   b6:
78     goto c6;
79   case 7:
80     halt()
81       +
82       dead();   // expected-warning {{will never be executed}}
83     -           // expected-warning {{will never be executed}}
84       halt();
85   case 8:
86     i
87       +=        // expected-warning {{will never be executed}}
88       halt();
89   case 9:
90     halt()
91       ?         // expected-warning {{will never be executed}}
92       dead() : dead();
93   case 10:
94     (           // expected-warning {{will never be executed}}
95       float)halt();
96   case 11: {
97     int a[5];
98     live(),
99       a[halt()
100         ];      // expected-warning {{will never be executed}}
101   }
102   }
103 }
104 
105 enum Cases { C1, C2, C3 };
test_enum_cases(enum Cases C)106 int test_enum_cases(enum Cases C) {
107   switch (C) {
108     case C1:
109     case C2:
110     case C3:
111       return 1;
112     default: {
113       int i = 0; // no-warning
114       ++i;
115       return i;
116     }
117   }
118 }
119 
120 // Handle unreachable code triggered by macro expansions.
121 void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
122 
123 #define myassert(e) \
124     (__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
125 
test_assert(void)126 void test_assert(void) {
127   myassert(0 && "unreachable");
128   return; // no-warning
129 }
130 
131 // Test case for PR 9774.  Tests that dead code in macros aren't warned about.
132 #define MY_MAX(a,b)     ((a) >= (b) ? (a) : (b))
PR9774(int * s)133 void PR9774(int *s) {
134     for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning
135         s[i] = 0;
136 }
137 
138 // We should treat code guarded by 'x & 0' and 'x * 0' as unreachable.
139 int calledFun(void);
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(void) __attribute__((noreturn));
148 void warn_here(void);
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(void)195 int trivial_dead_return(void) {
196   raze();
197   return ((0)); // expected-warning {{'return' will never be executed}}
198 }
199 
trivial_dead_return_void(void)200 void trivial_dead_return_void(void) {
201   raze();
202   return; // expected-warning {{'return' will never be executed}}
203 }
204 
trivial_dead_return_enum(void)205 MyEnum trivial_dead_return_enum(void) {
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(void)221 const char *trivial_dead_return_cstr(void) {
222   raze();
223   return ""; // expected-warning {{return' will never be executed}}
224 }
225 
trivial_dead_return_char(void)226 char trivial_dead_return_char(void) {
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(void)291 int test_MyEnum(void) {
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(void)331 void trivial_dead_return_void_SUPPRESSED(void) {
332   raze();
333   return; // no-warning
334 }
335 
trivial_dead_return_enum_SUPPRESSED(void)336 MyEnum trivial_dead_return_enum_SUPPRESSED(void) {
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 
400 struct StructWithPointer {
401   void *p;
402 };
403 
emitJustOneWarningForOr(struct StructWithPointer * s)404 void emitJustOneWarningForOr(struct StructWithPointer *s) {
405   if (1 || !s->p) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
406     return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
407             // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:8}:")"
408   emitJustOneWarningForOr(s); // expected-warning {{code will never be executed}}
409 }
410 
emitJustOneWarningForOrSilenced(struct StructWithPointer * s)411 void emitJustOneWarningForOrSilenced(struct StructWithPointer *s) {
412   if ((1) || !s->p)
413     return;
414 
415   emitJustOneWarningForOrSilenced(s); // no warning
416 }
417 
emitJustOneWarningForOr2(struct StructWithPointer * s)418 void emitJustOneWarningForOr2(struct StructWithPointer *s) {
419   if (1 || !s->p) // expected-warning {{code will never be executed}}
420     return; // expected-note@-1 {{silence by adding parentheses to mark code as explicitly dead}}
421   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:7}:"/* DISABLES CODE */ ("
422   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:")"
423 }
424 
wrapOneInFixit(struct StructWithPointer * s)425 void wrapOneInFixit(struct StructWithPointer *s) {
426   if (!s->p || 1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
427     return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"/* DISABLES CODE */ ("
428             // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:")"
429   wrapOneInFixit(s); // expected-warning {{code will never be executed}}
430 }
431 
unaryOpNoFixit(void)432 void unaryOpNoFixit(void) {
433   if (~ 1)
434     return; // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
435   unaryOpNoFixit(); // expected-warning {{code will never be executed}}
436 }
437 
unaryOpStrictFixit(struct StructWithPointer * s)438 void unaryOpStrictFixit(struct StructWithPointer *s) {
439   if (!(s->p && 0)) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
440     return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"/* DISABLES CODE */ ("
441             // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:")"
442   unaryOpStrictFixit(s); // expected-warning {{code will never be executed}}
443 }
444 
unaryOpFixitCastSubExpr(int x)445 void unaryOpFixitCastSubExpr(int x) {
446   if (! (int)0) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
447     return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
448             // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:")"
449   unaryOpFixitCastSubExpr(x); // expected-warning {{code will never be executed}}
450 }
451 
452 #define false 0
453 #define true 1
454 
testTrueFalseMacros(void)455 void testTrueFalseMacros(void) {
456   if (false) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
457     testTrueFalseMacros(); // expected-warning {{code will never be executed}}
458   if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
459     testTrueFalseMacros(); // expected-warning {{code will never be executed}}
460 }
461 
pr13910_foo(int x)462 int pr13910_foo(int x) {
463   if (x == 1)
464     return 0;
465   else
466     return x;
467   __builtin_unreachable(); // expected no warning
468   __builtin_assume(0); // expected no warning
469 }
470 
pr13910_bar(int x)471 int pr13910_bar(int x) {
472   switch (x) {
473   default:
474     return x + 1;
475   }
476   pr13910_foo(x); // expected-warning {{code will never be executed}}
477 }
478 
pr13910_bar2(int x)479 int pr13910_bar2(int x) {
480   if (x == 1)
481     return 0;
482   else
483     return x;
484   pr13910_foo(x);          // expected-warning {{code will never be executed}}
485   __builtin_unreachable(); // expected no warning
486   __builtin_assume(0);     // expected no warning
487   pr13910_foo(x);          // expected-warning {{code will never be executed}}
488 }
489 
pr13910_noreturn(void)490 void pr13910_noreturn(void) {
491   raze();
492   __builtin_unreachable(); // expected no warning
493   __builtin_assume(0); // expected no warning
494 }
495 
pr13910_assert(void)496 void pr13910_assert(void) {
497   myassert(0 && "unreachable");
498   return;
499   __builtin_unreachable(); // expected no warning
500   __builtin_assume(0); // expected no warning
501 }
502