Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range -Wno-tautological-compare %s
      2 
      3 void clang_analyzer_eval(bool);
      4 
      5 #define UINT_MAX (~0U)
      6 #define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
      7 #define INT_MIN (-INT_MAX - 1)
      8 
      9 //---------------
     10 //  Plus/minus
     11 //---------------
     12 
     13 void separateExpressions (int a) {
     14   int b = a + 1;
     15   --b;
     16 
     17   clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
     18 }
     19 
     20 void oneLongExpression (int a) {
     21   // Expression canonicalization should still allow this to work, even though
     22   // the first term is on the left.
     23   int b = 15 + a + 15 - 10 - 20;
     24 
     25   clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
     26 }
     27 
     28 void mixedTypes (int a) {
     29   // Different additive types should not cause crashes when constant-folding.
     30   // This is part of PR7406.
     31   int b = a + 1LL;
     32   clang_analyzer_eval(a != 0 && (b-1) == 0); // not crash, expected-warning{{FALSE}}
     33 
     34   int c = a + 1U;
     35   clang_analyzer_eval(a != 0 && (c-1) == 0); // not crash, expected-warning{{FALSE}}
     36 }
     37 
     38 //---------------
     39 //  Comparisons
     40 //---------------
     41 
     42 // Equality and inequality only
     43 void eq_ne (unsigned a) {
     44   if (a == UINT_MAX) {
     45     clang_analyzer_eval(a+1 == 0); // expected-warning{{TRUE}}
     46     clang_analyzer_eval(a-1 == UINT_MAX-1); // expected-warning{{TRUE}}
     47   } else {
     48     clang_analyzer_eval(a+1 != 0); // expected-warning{{TRUE}}
     49     clang_analyzer_eval(a-1 != UINT_MAX-1); // expected-warning{{TRUE}}
     50   }
     51 }
     52 
     53 // Mixed typed inequalities (part of PR7406)
     54 // These should not crash.
     55 void mixed_eq_ne (int a) {
     56   if (a == 1) {
     57     clang_analyzer_eval(a+1U == 2); // expected-warning{{TRUE}}
     58     clang_analyzer_eval(a-1U == 0); // expected-warning{{TRUE}}
     59   } else {
     60     clang_analyzer_eval(a+1U != 2); // expected-warning{{TRUE}}
     61     clang_analyzer_eval(a-1U != 0); // expected-warning{{TRUE}}
     62   }
     63 }
     64 
     65 
     66 // Simple order comparisons with no adjustment
     67 void baselineGT (unsigned a) {
     68   if (a > 0)
     69     clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
     70   else
     71     clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
     72 }
     73 
     74 void baselineGE (unsigned a) {
     75   if (a >= UINT_MAX)
     76     clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
     77   else
     78     clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
     79 }
     80 
     81 void baselineLT (unsigned a) {
     82   if (a < UINT_MAX)
     83     clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
     84   else
     85     clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
     86 }
     87 
     88 void baselineLE (unsigned a) {
     89   if (a <= 0)
     90     clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
     91   else
     92     clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
     93 }
     94 
     95 
     96 // Adjustment gives each of these an extra solution!
     97 void adjustedGT (unsigned a) {
     98   clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
     99 }
    100 
    101 void adjustedGE (unsigned a) {
    102   clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
    103 
    104   if (a-1 >= UINT_MAX-1)
    105     clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
    106 }
    107 
    108 void adjustedLT (unsigned a) {
    109   clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}}
    110 }
    111 
    112 void adjustedLE (unsigned a) {
    113   clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}}
    114 
    115   if (a+1 <= 1)
    116     clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
    117 }
    118 
    119 
    120 // Tautologies
    121 // The negative forms are exercised as well
    122 // because clang_analyzer_eval tests both possibilities.
    123 void tautologies(unsigned a) {
    124   clang_analyzer_eval(a <= UINT_MAX); // expected-warning{{TRUE}}
    125   clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
    126 }
    127 
    128 
    129 // Tautologies from outside the range of the symbol
    130 void tautologiesOutside(unsigned char a) {
    131   clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}}
    132   clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}}
    133 
    134   clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}}
    135   clang_analyzer_eval(a != -1); // expected-warning{{TRUE}}
    136 
    137   clang_analyzer_eval(a > -1); // expected-warning{{TRUE}}
    138   clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}}
    139 }
    140 
    141 
    142 // Wraparound with mixed types. Note that the analyzer assumes
    143 // -fwrapv semantics.
    144 void mixedWraparoundSanityCheck(int a) {
    145   int max = INT_MAX;
    146   int min = INT_MIN;
    147 
    148   int b = a + 1;
    149   clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}}
    150 }
    151 
    152 void mixedWraparoundLE_GT(int a) {
    153   int max = INT_MAX;
    154   int min = INT_MIN;
    155 
    156   clang_analyzer_eval((a + 2) <= (max + 1LL)); // expected-warning{{TRUE}}
    157   clang_analyzer_eval((a - 2) > (min - 1LL)); // expected-warning{{TRUE}}
    158   clang_analyzer_eval((a + 2LL) <= max); // expected-warning{{UNKNOWN}}
    159 }
    160 
    161 void mixedWraparoundGE_LT(int a) {
    162   int max = INT_MAX;
    163   int min = INT_MIN;
    164 
    165   clang_analyzer_eval((a + 2) < (max + 1LL)); // expected-warning{{TRUE}}
    166   clang_analyzer_eval((a - 2) >= (min - 1LL)); // expected-warning{{TRUE}}
    167   clang_analyzer_eval((a - 2LL) >= min); // expected-warning{{UNKNOWN}}
    168 }
    169 
    170 void mixedWraparoundEQ_NE(int a) {
    171   int max = INT_MAX;
    172 
    173   clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}}
    174   clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}}
    175 }
    176 
    177 
    178 // Mixed-signedness comparisons.
    179 void mixedSignedness(int a, unsigned b) {
    180   int sMin = INT_MIN;
    181   unsigned uMin = INT_MIN;
    182 
    183   clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}}
    184   clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}}
    185 }
    186 
    187 void mixedSignedness2(int a) {
    188   if (a != -1)
    189     return;
    190   clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
    191 }
    192 
    193 void mixedSignedness3(unsigned a) {
    194   if (a != UINT_MAX)
    195     return;
    196   clang_analyzer_eval(a == -1); // expected-warning{{TRUE}}
    197 }
    198 
    199 
    200 void multiplicativeSanityTest(int x) {
    201   // At one point we were ignoring the *4 completely -- the constraint manager
    202   // would see x < 8 and then declare the assertion to be known false.
    203   if (x*4 < 8)
    204     return;
    205 
    206   clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
    207 }
    208