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