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