217 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare -analyzer-config eagerly-assume=false %s2 3void 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/minus11//---------------12 13void separateExpressions (int a) {14 int b = a + 1;15 --b;16 17 clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}18}19 20void oneLongExpression (int a) {21 // Expression canonicalization should still allow this to work, even though22 // 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 28void 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// Comparisons40//---------------41 42// Equality and inequality only43void 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.55void 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 adjustment67void baselineGT (unsigned a) {68 if (a > 0)69 clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}70 else71 clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}72}73 74void baselineGE (unsigned a) {75 if (a >= UINT_MAX)76 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}77 else78 clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}79}80 81void baselineLT (unsigned a) {82 if (a < UINT_MAX)83 clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}84 else85 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}86}87 88void baselineLE (unsigned a) {89 if (a <= 0)90 clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}91 else92 clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}93}94 95 96// Adjustment gives each of these an extra solution!97void adjustedGT (unsigned a) {98 clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}99}100 101void 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 108void adjustedLT (unsigned a) {109 clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}}110}111 112void 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// Tautologies121// The negative forms are exercised as well122// because clang_analyzer_eval tests both possibilities.123void 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 symbol130void 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 assumes143// -fwrapv semantics.144void mixedWraparoundBasicCheck(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 152void 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 161void 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 170void 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.179void 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 187void mixedSignedness2(int a) {188 if (a != -1)189 return;190 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}191}192 193void mixedSignedness3(unsigned a) {194 if (a != UINT_MAX)195 return;196 clang_analyzer_eval(a == -1); // expected-warning{{TRUE}}197}198 199 200void multiplicativeBasicTest(int x) {201 // At one point we were ignoring the *4 completely -- the constraint manager202 // 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 209void additiveSymSymFolding(int x, int y) {210 // We should simplify 'x - 1' to '0' and handle the comparison,211 // despite both sides being complicated symbols.212 int z = x - 1;213 if (x == 1)214 if (y >= 0)215 clang_analyzer_eval(z <= y); // expected-warning{{TRUE}}216}217