Clang Project

clang_source_code/test/Sema/warn-unreachable.c
1// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs
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
6int halt() __attribute__((noreturn));
7int live();
8int dead();
9
10void test1() {
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
29void test2() {
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
105enum Cases { C1, C2, C3 };
106int 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.
121void __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
126void test_assert() {
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))
133void PR9774(int *s) {
134    for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning
135        s[i] = 0;
136}
137
138// Test case for <rdar://problem/11005770>.  We should treat code guarded
139// by 'x & 0' and 'x * 0' as unreachable.
140int calledFun();
141void test_mul_and_zero(int x) {
142  if (x & 0) calledFun(); // expected-warning {{will never be executed}}
143  if (0 & x) calledFun(); // expected-warning {{will never be executed}}
144  if (x * 0) calledFun(); // expected-warning {{will never be executed}}
145  if (0 * x) calledFun(); // expected-warning {{will never be executed}}
146}
147
148void raze() __attribute__((noreturn));
149void warn_here();
150
151int test_break_preceded_by_noreturn(int i) {
152  switch (i) {
153    case 1:
154      raze();
155      break; // expected-warning {{'break' will never be executed}}
156    case 2:
157      raze();
158      break; // expected-warning {{'break' will never be executed}}
159      warn_here(); // expected-warning {{will never be executed}}
160    case 3:
161      return 1;
162      break; // expected-warning {{will never be executed}}
163    default:
164      break;
165      break; // expected-warning {{will never be executed}}
166  }
167  return i;
168}
169
170// Don't warn about unreachable 'default' cases, as that is covered
171// by -Wcovered-switch-default.
172typedef enum { Value1 = 1 } MyEnum;
173void unreachable_default(MyEnum e) {
174  switch (e) {
175  case Value1:
176    calledFun();
177    break;
178  case 2: // expected-warning {{case value not in enumerated type 'MyEnum'}}
179    calledFun();
180    break;
181  default:
182    calledFun(); // no-warning
183    break;
184  }
185}
186void unreachable_in_default(MyEnum e) {
187  switch (e) {
188  default:
189    raze();
190    calledFun(); // expected-warning {{will never be executed}}
191    break;
192  }
193}
194
195// Don't warn about trivial dead returns.
196int trivial_dead_return() {
197  raze();
198  return ((0)); // expected-warning {{'return' will never be executed}}
199}
200
201void trivial_dead_return_void() {
202  raze();
203  return; // expected-warning {{'return' will never be executed}}
204}
205
206MyEnum trivial_dead_return_enum() {
207  raze();
208  return Value1; // expected-warning {{'return' will never be executed}}
209}
210
211MyEnum trivial_dead_return_enum_2(int x) {
212  switch (x) {
213    case 1: return 1;
214    case 2: return 2;
215    case 3: return 3;
216    default: return 4;
217  }
218
219  return 2; // expected-warning {{will never be executed}}
220}
221
222const char *trivial_dead_return_cstr() {
223  raze();
224  return ""; // expected-warning {{return' will never be executed}}
225}
226
227char trivial_dead_return_char() {
228  raze();
229  return ' '; // expected-warning {{return' will never be executed}}
230}
231
232MyEnum nontrivial_dead_return_enum_2(int x) {
233  switch (x) {
234    case 1: return 1;
235    case 2: return 2;
236    case 3: return 3;
237    default: return 4;
238  }
239
240  return calledFun(); // expected-warning {{will never be executed}}
241}
242
243enum X { A, B, C };
244
245int covered_switch(enum X x) {
246  switch (x) {
247  case A: return 1;
248  case B: return 2;
249  case C: return 3;
250  }
251  return 4; // no-warning
252}
253
254// Test unreachable code depending on configuration values
255#define CONFIG_CONSTANT 1
256int test_config_constant(int x) {
257  if (!CONFIG_CONSTANT) {
258    calledFun(); // no-warning
259    return 1;
260  }
261  if (!1) { // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
262    calledFun(); // expected-warning {{will never be executed}}
263    return 1;
264  }
265  if (sizeof(int) > sizeof(char)) {
266    calledFun(); // no-warning
267    return 1;
268  }
269  if (x > 10)
270    return CONFIG_CONSTANT ? calledFun() : calledFun(); // no-warning
271  else
272    return 1 ? // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
273      calledFun() :
274      calledFun(); // expected-warning {{will never be executed}}
275}
276
277int sizeof_int(int x, int y) {
278  if (sizeof(long) == sizeof(int))
279    return 1; // no-warning
280  if (sizeof(long) != sizeof(int))
281    return 0; // no-warning
282  if (x && y && sizeof(long) < sizeof(char))
283    return 0; // no-warning
284  return 2; // no-warning
285}
286
287enum MyEnum2 {
288  ME_A = CONFIG_CONSTANT,
289  ME_B = 1
290};
291
292int test_MyEnum() {
293  if (!ME_A)
294    return 1; // no-warning
295  if (ME_A)
296    return 2; // no-warning
297  if (ME_B)
298    return 3;
299  if (!ME_B) // expected-warning {{will never be executed}}
300    return 4; // expected-warning {{will never be executed}}
301  return 5;
302}
303
304// Test for idiomatic do..while.
305int test_do_while(int x) {
306  do {
307    if (x == calledFun())
308      break;
309    ++x;
310    break;
311  }
312  while (0); // no-warning
313  return x;
314}
315
316int test_do_while_nontrivial_cond(int x) {
317  do {
318    if (x == calledFun())
319      break;
320    ++x;
321    break;
322  }
323  while (calledFun()); // expected-warning {{will never be executed}}
324  return x;
325}
326
327// Diagnostic control: -Wunreachable-code-return.
328
329#pragma clang diagnostic push
330#pragma clang diagnostic ignored "-Wunreachable-code-return"
331
332void trivial_dead_return_void_SUPPRESSED() {
333  raze();
334  return; // no-warning
335}
336
337MyEnum trivial_dead_return_enum_SUPPRESSED() {
338  raze();
339  return Value1; // no-warning
340}
341
342#pragma clang diagnostic pop
343
344// Diagnostic control: -Wunreachable-code-break.
345
346#pragma clang diagnostic push
347#pragma clang diagnostic ignored "-Wunreachable-code-break"
348
349int test_break_preceded_by_noreturn_SUPPRESSED(int i) {
350  switch (i) {
351    case 1:
352      raze();
353      break; // no-warning
354    case 2:
355      raze();
356      break; // no-warning
357      warn_here(); // expected-warning {{will never be executed}}
358    case 3:
359      return 1;
360      break; // no-warning
361    default:
362      break;
363      break; // no-warning
364  }
365  return i;
366}
367
368#pragma clang diagnostic pop
369
370// Test "silencing" with parentheses.
371void test_with_paren_silencing(int x) {
372  if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
373  if ((0)) calledFun(); // no-warning
374
375  if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
376    calledFun();
377  else
378    calledFun(); // expected-warning {{will never be executed}}
379
380  if ((1))
381    calledFun();
382  else
383    calledFun(); // no-warning
384  
385  if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
386    calledFun(); // expected-warning {{code will never be executed}}
387  else
388    calledFun();
389  
390  if ((!1))
391    calledFun(); // no-warning
392  else
393    calledFun();
394  
395  if (!(1))
396    calledFun(); // no-warning
397  else
398    calledFun();
399}
400
401// rdar://24570531
402
403struct StructWithPointer {
404  void *p;
405};
406
407void emitJustOneWarningForOr(struct StructWithPointer *s) {
408  if (1 || !s->p) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
409    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
410            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:8}:")"
411  emitJustOneWarningForOr(s); // expected-warning {{code will never be executed}}
412}
413
414void emitJustOneWarningForOrSilenced(struct StructWithPointer *s) {
415  if ((1) || !s->p)
416    return;
417
418  emitJustOneWarningForOrSilenced(s); // no warning
419}
420
421void emitJustOneWarningForOr2(struct StructWithPointer *s) {
422  if (1 || !s->p) // expected-warning {{code will never be executed}}
423    return; // expected-note@-1 {{silence by adding parentheses to mark code as explicitly dead}}
424  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:7}:"/* DISABLES CODE */ ("
425  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:")"
426}
427
428void wrapOneInFixit(struct StructWithPointer *s) {
429  if (!s->p || 1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
430    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"/* DISABLES CODE */ ("
431            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:")"
432  wrapOneInFixit(s); // expected-warning {{code will never be executed}}
433}
434
435void unaryOpNoFixit() {
436  if (- 1)
437    return; // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
438  unaryOpNoFixit(); // expected-warning {{code will never be executed}}
439}
440
441void unaryOpStrictFixit(struct StructWithPointer *s) {
442  if (!(s->p && 0)) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
443    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"/* DISABLES CODE */ ("
444            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:")"
445  unaryOpStrictFixit(s); // expected-warning {{code will never be executed}}
446}
447
448void unaryOpFixitCastSubExpr(int x) {
449  if (! (int)0) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
450    return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
451            // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:")"
452  unaryOpFixitCastSubExpr(x); // expected-warning {{code will never be executed}}
453}
454
455#define false 0
456#define true 1
457
458void testTrueFalseMacros() {
459  if (false) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
460    testTrueFalseMacros(); // expected-warning {{code will never be executed}}
461  if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
462    testTrueFalseMacros(); // expected-warning {{code will never be executed}}
463}
464
465int pr13910_foo(int x) {
466  if (x == 1)
467    return 0;
468  else
469    return x;
470  __builtin_unreachable(); // expected no warning
471  __builtin_assume(0); // expected no warning
472}
473
474int pr13910_bar(int x) {
475  switch (x) {
476  default:
477    return x + 1;
478  }
479  pr13910_foo(x); // expected-warning {{code will never be executed}}
480}
481
482int pr13910_bar2(int x) {
483  if (x == 1)
484    return 0;
485  else
486    return x;
487  pr13910_foo(x);          // expected-warning {{code will never be executed}}
488  __builtin_unreachable(); // expected no warning
489  __builtin_assume(0);     // expected no warning
490  pr13910_foo(x);          // expected-warning {{code will never be executed}}
491}
492
493void pr13910_noreturn() {
494  raze();
495  __builtin_unreachable(); // expected no warning
496  __builtin_assume(0); // expected no warning
497}
498
499void pr13910_assert() {
500  myassert(0 && "unreachable");
501  return;
502  __builtin_unreachable(); // expected no warning
503  __builtin_assume(0); // expected no warning
504}
505