Home | History | Annotate | Download | only in Analysis
      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 
      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 
     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 
     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 
     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 
     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 
     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 };
     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 
     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
     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
    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();
    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 
    143 void inlined(int condition) {
    144   if (condition) {
    145     foo(5); // no-warning
    146   } else {
    147     foo(6);
    148   }
    149 }
    150 
    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