Richard Trieu | 526e627 | 2012-11-14 22:50:24 +0000 | [diff] [blame] | 1 | // 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] | 2 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 3 | void clang_analyzer_eval(bool); |
| 4 | |
Jordy Rose | 9e607dd | 2012-05-03 07:33:56 +0000 | [diff] [blame] | 5 | #define UINT_MAX (~0U) |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 6 | #define INT_MAX (UINT_MAX & (UINT_MAX >> 1)) |
| 7 | #define INT_MIN (-INT_MAX - 1) |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 8 | |
| 9 | //--------------- |
| 10 | // Plus/minus |
| 11 | //--------------- |
| 12 | |
| 13 | void separateExpressions (int a) { |
| 14 | int b = a + 1; |
| 15 | --b; |
| 16 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 17 | clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 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 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 25 | clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 26 | } |
| 27 | |
Jordy Rose | b4954a4 | 2010-06-21 20:15:15 +0000 | [diff] [blame] | 28 | void mixedTypes (int a) { |
Jordy Rose | b4954a4 | 2010-06-21 20:15:15 +0000 | [diff] [blame] | 29 | // Different additive types should not cause crashes when constant-folding. |
| 30 | // This is part of PR7406. |
| 31 | int b = a + 1LL; |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 32 | 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] | 33 | |
| 34 | int c = a + 1U; |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 35 | 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] | 36 | } |
| 37 | |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 38 | //--------------- |
| 39 | // Comparisons |
| 40 | //--------------- |
| 41 | |
| 42 | // Equality and inequality only |
| 43 | void eq_ne (unsigned a) { |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 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 | } |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 51 | } |
| 52 | |
Jordy Rose | b4954a4 | 2010-06-21 20:15:15 +0000 | [diff] [blame] | 53 | // Mixed typed inequalities (part of PR7406) |
| 54 | // These should not crash. |
| 55 | void mixed_eq_ne (int a) { |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 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 | } |
Jordy Rose | b4954a4 | 2010-06-21 20:15:15 +0000 | [diff] [blame] | 63 | } |
| 64 | |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 65 | |
| 66 | // Simple order comparisons with no adjustment |
| 67 | void baselineGT (unsigned a) { |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 68 | if (a > 0) |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 69 | clang_analyzer_eval(a != 0); // expected-warning{{TRUE}} |
| 70 | else |
| 71 | clang_analyzer_eval(a == 0); // expected-warning{{TRUE}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | void baselineGE (unsigned a) { |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 75 | if (a >= UINT_MAX) |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 76 | clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}} |
| 77 | else |
| 78 | clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | void baselineLT (unsigned a) { |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 82 | if (a < UINT_MAX) |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 83 | clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}} |
| 84 | else |
| 85 | clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | void baselineLE (unsigned a) { |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 89 | if (a <= 0) |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 90 | clang_analyzer_eval(a == 0); // expected-warning{{TRUE}} |
| 91 | else |
| 92 | clang_analyzer_eval(a != 0); // expected-warning{{TRUE}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | |
| 96 | // Adjustment gives each of these an extra solution! |
| 97 | void adjustedGT (unsigned a) { |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 98 | clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | void adjustedGE (unsigned a) { |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 102 | clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}} |
| 103 | |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 104 | if (a-1 >= UINT_MAX-1) |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 105 | clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | void adjustedLT (unsigned a) { |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 109 | clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | void adjustedLE (unsigned a) { |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 113 | clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}} |
| 114 | |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 115 | if (a+1 <= 1) |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 116 | clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | |
| 120 | // Tautologies |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 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}} |
Jordy Rose | ba0f61c | 2010-06-18 22:49:11 +0000 | [diff] [blame] | 126 | } |
Jordy Rose | 14d20b1 | 2012-05-03 07:34:01 +0000 | [diff] [blame] | 127 | |
| 128 | |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 129 | // Tautologies from outside the range of the symbol |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 130 | void tautologiesOutside(unsigned char a) { |
Richard Trieu | 526e627 | 2012-11-14 22:50:24 +0000 | [diff] [blame] | 131 | clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}} |
| 132 | clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 133 | |
Richard Trieu | 526e627 | 2012-11-14 22:50:24 +0000 | [diff] [blame] | 134 | clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}} |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 135 | clang_analyzer_eval(a != -1); // expected-warning{{TRUE}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 136 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 137 | clang_analyzer_eval(a > -1); // expected-warning{{TRUE}} |
| 138 | clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 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; |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 149 | clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 150 | } |
| 151 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 152 | void mixedWraparoundLE_GT(int a) { |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 153 | int max = INT_MAX; |
| 154 | int min = INT_MIN; |
| 155 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 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}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 159 | } |
| 160 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 161 | void mixedWraparoundGE_LT(int a) { |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 162 | int max = INT_MAX; |
| 163 | int min = INT_MIN; |
| 164 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 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}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 168 | } |
| 169 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 170 | void mixedWraparoundEQ_NE(int a) { |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 171 | int max = INT_MAX; |
| 172 | |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 173 | clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}} |
| 174 | clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | |
| 178 | // Mixed-signedness comparisons. |
| 179 | void mixedSignedness(int a, unsigned b) { |
| 180 | int sMin = INT_MIN; |
| 181 | unsigned uMin = INT_MIN; |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 182 | |
| 183 | clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}} |
| 184 | clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 185 | } |
| 186 | |
Jordan Rose | 4708b3d | 2013-03-23 01:21:33 +0000 | [diff] [blame^] | 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 | |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 199 | |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 200 | void multiplicativeSanityTest(int x) { |
| 201 | // At one point we were ignoring the *4 completely -- the constraint manager |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 202 | // 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] | 203 | if (x*4 < 8) |
| 204 | return; |
Jordy Rose | 43d9f0d | 2012-05-16 16:01:10 +0000 | [diff] [blame] | 205 | |
| 206 | clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}} |
Jordy Rose | 1d8db49 | 2012-05-08 03:27:16 +0000 | [diff] [blame] | 207 | } |