Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
      2 
      3 void clang_analyzer_eval(int);
      4 void clang_analyzer_warnIfReached();
      5 
      6 #define INT_MIN 0x80000000
      7 #define INT_MAX 0x7fffffff
      8 
      9 // PR16833: Analyzer consumes memory until killed by kernel OOM killer
     10 // while analyzing large case ranges.
     11 void PR16833(unsigned op) {
     12   switch (op) {
     13   case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here.
     14     return;
     15   }
     16 }
     17 
     18 void testAdjustment(int t) {
     19   switch (t + 1) {
     20   case 2:
     21     clang_analyzer_eval(t == 1); // expected-warning{{TRUE}}
     22     break;
     23   case 3 ... 10:
     24     clang_analyzer_eval(t > 1);        // expected-warning{{TRUE}}
     25     clang_analyzer_eval(t + 2 <= 11);  // expected-warning{{TRUE}}
     26     clang_analyzer_eval(t > 2);        // expected-warning{{UNKNOWN}}
     27     clang_analyzer_eval(t + 1 == 3);   // expected-warning{{UNKNOWN}}
     28     clang_analyzer_eval(t + 1 == 10);  // expected-warning{{UNKNOWN}}
     29     break;
     30   default:
     31     clang_analyzer_warnIfReached();    // expected-warning{{REACHABLE}}
     32   }
     33 }
     34 
     35 void testUnknownVal(int value, int mask) {
     36   // Once ConstraintManager will process '&' and this test will require some changes.
     37   switch (value & mask) {
     38     case 1:
     39       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
     40       break;
     41     case 3 ... 10:
     42       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
     43       break;
     44     default:
     45       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
     46   }
     47 }
     48 
     49 void testSwitchCond(int arg) {
     50   if (arg > 10) {
     51     switch (arg) {
     52     case INT_MIN ... 10:
     53       clang_analyzer_warnIfReached(); // no-warning
     54       break;
     55     case 11 ... 20:
     56       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
     57       break;
     58     default:
     59       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
     60     }
     61 
     62     switch (arg) {
     63     case INT_MIN ... 9:
     64       clang_analyzer_warnIfReached();  // no-warning
     65       break;
     66     case 10 ... 20:
     67       clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
     68       clang_analyzer_eval(arg > 10);   // expected-warning{{TRUE}}
     69       break;
     70     default:
     71       clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
     72     }
     73   } // arg > 10
     74 }
     75 
     76 void testDefaultUnreachable(int arg) {
     77   if (arg > 10) {
     78     switch (arg) {
     79     case INT_MIN ... 9:
     80       clang_analyzer_warnIfReached();   // no-warning
     81       break;
     82     case 10 ... INT_MAX:
     83       clang_analyzer_warnIfReached();   // expected-warning{{REACHABLE}}
     84       clang_analyzer_eval(arg > 10);    // expected-warning{{TRUE}}
     85       break;
     86     default:
     87       clang_analyzer_warnIfReached();   // no-warning
     88     }
     89   }
     90 }
     91 
     92 void testBranchReachability(int arg) {
     93   if (arg > 10 && arg < 20) {
     94     switch (arg) {
     95     case INT_MIN ... 4:
     96       clang_analyzer_warnIfReached(); // no-warning
     97       break;
     98     case 5 ... 9:
     99       clang_analyzer_warnIfReached(); // no-warning
    100       break;
    101     case 10 ... 15:
    102       clang_analyzer_warnIfReached();              // expected-warning{{REACHABLE}}
    103       clang_analyzer_eval(arg > 10 && arg <= 15);  // expected-warning{{TRUE}}
    104       break;
    105     default:
    106       clang_analyzer_warnIfReached(); // no-warning
    107       break;
    108     case 17 ... 25:
    109       clang_analyzer_warnIfReached();              // expected-warning{{REACHABLE}}
    110       clang_analyzer_eval(arg >= 17 && arg < 20);  // expected-warning{{TRUE}}
    111       break;
    112     case 26 ... INT_MAX:
    113       clang_analyzer_warnIfReached();   // no-warning
    114       break;
    115     case 16:
    116       clang_analyzer_warnIfReached();   // expected-warning{{REACHABLE}}
    117       clang_analyzer_eval(arg == 16);   // expected-warning{{TRUE}}
    118       break;
    119     }
    120   }
    121 }
    122 
    123 void testDefaultBranchRange(int arg) {
    124   switch (arg) {
    125   case INT_MIN ... 9:
    126     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
    127     break;
    128   case 20 ... INT_MAX:
    129     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
    130     clang_analyzer_eval(arg >= 20);  // expected-warning{{TRUE}}
    131     break;
    132   default:
    133     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
    134     clang_analyzer_eval(arg == 16);  // expected-warning{{FALSE}}
    135     clang_analyzer_eval(arg > 9);    // expected-warning{{TRUE}}
    136     clang_analyzer_eval(arg <= 20);  // expected-warning{{TRUE}}
    137 
    138   case 16:
    139     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
    140   }
    141 }
    142 
    143 void testAllUnreachableButDefault(int arg) {
    144   if (arg < 0) {
    145     switch (arg) {
    146     case 0 ... 9:
    147       clang_analyzer_warnIfReached(); // no-warning
    148       break;
    149     case 20 ... INT_MAX:
    150       clang_analyzer_warnIfReached(); // no-warning
    151       break;
    152     default:
    153       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    154       break;
    155     case 16:
    156       clang_analyzer_warnIfReached(); // no-warning
    157     }
    158     clang_analyzer_warnIfReached();   // expected-warning{{REACHABLE}}
    159   }
    160 }
    161 
    162 void testAllUnreachable(int arg) {
    163   if (arg < 0) {
    164     switch (arg) {
    165     case 0 ... 9:
    166       clang_analyzer_warnIfReached(); // no-warning
    167       break;
    168     case 20 ... INT_MAX:
    169       clang_analyzer_warnIfReached(); // no-warning
    170       break;
    171     case 16:
    172       clang_analyzer_warnIfReached(); // no-warning
    173     }
    174     clang_analyzer_warnIfReached();   // expected-warning{{REACHABLE}}
    175   }
    176 }
    177 
    178 void testDifferentTypes(int arg) {
    179   switch (arg) {
    180   case -1U ... 400000000LL:
    181       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    182       break;
    183     default:
    184       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    185       break;
    186   }
    187 }
    188 
    189 void testDifferentTypes2(unsigned long arg) {
    190   switch (arg) {
    191   case 1UL ... 400000000UL:
    192       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    193       break;
    194     default:
    195       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    196       break;
    197   }
    198 }
    199 
    200 void testDifferentTypes3(int arg) {
    201   switch (arg) {
    202   case 1UL ... 400000000UL:
    203       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    204       break;
    205     default:
    206       clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    207       break;
    208   }
    209 }
    210 
    211 void testConstant() {
    212   switch (3) {
    213   case 1 ... 5:
    214     clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
    215     break;
    216   default:
    217     clang_analyzer_warnIfReached(); // no-warning
    218     break;
    219   }
    220 }
    221