Home | History | Annotate | Download | only in Sema
      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 
      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 
     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 };
    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 
    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))
    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();
    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 
    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;
    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 }
    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.
    195 int trivial_dead_return() {
    196   raze();
    197   return ((0)); // expected-warning {{'return' will never be executed}}
    198 }
    199 
    200 void trivial_dead_return_void() {
    201   raze();
    202   return; // expected-warning {{'return' will never be executed}}
    203 }
    204 
    205 MyEnum trivial_dead_return_enum() {
    206   raze();
    207   return Value1; // expected-warning {{'return' will never be executed}}
    208 }
    209 
    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 
    221 const char *trivial_dead_return_cstr() {
    222   raze();
    223   return ""; // expected-warning {{return' will never be executed}}
    224 }
    225 
    226 char trivial_dead_return_char() {
    227   raze();
    228   return ' '; // expected-warning {{return' will never be executed}}
    229 }
    230 
    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 
    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
    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 
    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 
    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.
    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 
    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 
    331 void trivial_dead_return_void_SUPPRESSED() {
    332   raze();
    333   return; // no-warning
    334 }
    335 
    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 
    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.
    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