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