blob: b22eb2a5b345ecbca984d7c61edc1f37cd5405f7 [file] [log] [blame]
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range %s
Jordy Roseba0f61c2010-06-18 22:49:11 +00002
Jordy Rose43d9f0d2012-05-16 16:01:10 +00003void clang_analyzer_eval(int);
4
Jordy Rose9e607dd2012-05-03 07:33:56 +00005#define UINT_MAX (~0U)
Jordy Rose1d8db492012-05-08 03:27:16 +00006#define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
7#define INT_MIN (-INT_MAX - 1)
8
Jordy Roseba0f61c2010-06-18 22:49:11 +00009
10// Each of these adjusted ranges has an adjustment small enough to split the
11// solution range across an overflow boundary (Min for <, Max for >).
12// This corresponds to one set of branches in RangeConstraintManager.
13void smallAdjustmentGT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000014 if (a+2 > 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000015 clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
16 else
17 clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000018}
19
20void smallAdjustmentGE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000021 if (a+2 >= 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000022 clang_analyzer_eval(a < UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
23 else
24 clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000025}
26
27void smallAdjustmentLT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000028 if (a+1 < 2)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000029 clang_analyzer_eval(a == 0 || a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000030}
31
32void smallAdjustmentLE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000033 if (a+1 <= 2)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000034 clang_analyzer_eval(a == 0 || a == 1 || a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000035}
36
37
38// Each of these adjusted ranges has an adjustment large enough to push the
39// comparison value over an overflow boundary (Min for <, Max for >).
40// This corresponds to one set of branches in RangeConstraintManager.
41void largeAdjustmentGT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000042 if (a-2 > UINT_MAX-1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000043 clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
44 else
45 clang_analyzer_eval(a != 1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000046}
47
48void largeAdjustmentGE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000049 if (a-2 >= UINT_MAX-1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000050 clang_analyzer_eval(a == 1 || a == 0); // expected-warning{{TRUE}}
51 else
52 clang_analyzer_eval(a > 1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000053}
54
55void largeAdjustmentLT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000056 if (a+2 < 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000057 clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
58 else
59 clang_analyzer_eval(a != UINT_MAX-1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000060}
61
62void largeAdjustmentLE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000063 if (a+2 <= 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000064 clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
65 else
66 clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000067}
Jordy Rose1d8db492012-05-08 03:27:16 +000068
69
70// Test the nine cases in RangeConstraintManager's pinning logic.
Jordy Rose43d9f0d2012-05-16 16:01:10 +000071// For out-of-range tautologies, it may be the negation that actually
72// triggers the case in question.
Jordy Rose1d8db492012-05-08 03:27:16 +000073void mixedComparisons1(signed char a) {
74 // Case 1: The range is entirely below the symbol's range.
75 int min = INT_MIN;
76
Jordy Rose43d9f0d2012-05-16 16:01:10 +000077 clang_analyzer_eval((a - 2) >= (min + 5LL)); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +000078
Jordy Rose43d9f0d2012-05-16 16:01:10 +000079 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
80 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
81 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +000082}
83
84void mixedComparisons2(signed char a) {
85 // Case 2: Only the lower end of the range is outside.
Jordy Rose43d9f0d2012-05-16 16:01:10 +000086 clang_analyzer_eval((a - 5) < (-0x81LL)); // expected-warning{{UNKNOWN}}
87
Jordy Rose1d8db492012-05-08 03:27:16 +000088 if ((a - 5) < (-0x81LL)) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +000089 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
90 clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
91 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +000092 }
93}
94
95void mixedComparisons3(signed char a) {
96 // Case 3: The entire symbol range is covered.
Jordy Rose43d9f0d2012-05-16 16:01:10 +000097 clang_analyzer_eval((a - 0x200) < -0x100LL); // expected-warning{{TRUE}}
98
99 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
100 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
101 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000102}
103
104void mixedComparisons4(signed char a) {
105 // Case 4: The range wraps around, but the lower wrap is out-of-range.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000106 clang_analyzer_eval((a - 5) > 0LL); // expected-warning{{UNKNOWN}}
107
Jordy Rose1d8db492012-05-08 03:27:16 +0000108 if ((a - 5) > 0LL) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000109 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
110 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
111 clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000112 }
113}
114
115void mixedComparisons5(signed char a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000116 // Case 5: The range is inside and may or may not wrap.
117 clang_analyzer_eval((a + 5) == 0LL); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000118
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000119 if ((a + 5) == 0LL) {
120 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
121 clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
122 clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000123 } else {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000124 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
125 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
126 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000127 }
128}
129
130void mixedComparisons6(signed char a) {
131 // Case 6: Only the upper end of the range is outside.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000132 clang_analyzer_eval((a + 5) > 0x81LL); // expected-warning{{UNKNOWN}}
133
Jordy Rose1d8db492012-05-08 03:27:16 +0000134 if ((a + 5) > 0x81LL) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000135 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
136 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
137 clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000138 }
139}
140
141void mixedComparisons7(signed char a) {
142 // Case 7: The range wraps around but is entirely outside the symbol's range.
143 int min = INT_MIN;
144
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000145 clang_analyzer_eval((a + 2) >= (min + 5LL)); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000146
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000147 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
148 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
149 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000150}
151
152void mixedComparisons8(signed char a) {
153 // Case 8: The range wraps, but the upper wrap is out of range.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000154 clang_analyzer_eval((a + 5) < 0LL); // expected-warning{{UNKNOWN}}
155
Jordy Rose1d8db492012-05-08 03:27:16 +0000156 if ((a + 5) < 0LL) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000157 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
158 clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
159 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000160 }
161}
162
163void mixedComparisons9(signed char a) {
164 // Case 9: The range is entirely above the symbol's range.
165 int max = INT_MAX;
166
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000167 clang_analyzer_eval((a + 2) <= (max - 5LL)); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000168
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000169 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
170 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
171 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000172}
Jordan Rose4708b3d2013-03-23 01:21:33 +0000173
174
175void mixedSignedness1(int a) {
176 unsigned max = UINT_MAX;
177 clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
178 clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
179 clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
180}
181
182void mixedSignedness2(int a) {
183 unsigned max = UINT_MAX;
184 clang_analyzer_eval(a <= max); // expected-warning{{TRUE}}
185 clang_analyzer_eval((a + 2) <= max); // expected-warning{{TRUE}}
186 clang_analyzer_eval((a + 2U) <= max); // expected-warning{{TRUE}}
187}
188
189void mixedSignedness3(unsigned a) {
190 int max = INT_MAX;
191 clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
192 clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
193 clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
194}
195
196void mixedSignedness4(unsigned a) {
197 int max = INT_MAX;
198 clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}}
199 clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}}
200 clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}}
201}
202
203void mixedSignedness5(unsigned a) {
204 int min = INT_MIN;
205 clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
206 clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
207 clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}}
208}
209
210void mixedSignedness6(unsigned a) {
211 int min = INT_MIN;
212 clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
213 clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
214 clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
215}
216
217void mixedSignedness7(unsigned a) {
218 unsigned min = 0;
219 clang_analyzer_eval(a < min); // expected-warning{{FALSE}}
220 clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}}
221 clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
222}
223
224void mixedSignedness8(unsigned a) {
225 unsigned min = 0;
226 clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
227 clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
228 clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
229}
230
231void mixedSignedness9(unsigned a) {
232 int min = 0;
233 clang_analyzer_eval(a < min); // expected-warning{{FALSE}}
234 clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}}
235 clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
236}
237
238void mixedSignedness10(unsigned a) {
239 int min = 0;
240 clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
241 clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
242 clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
243}
244
245void mixedSignedness11(int a) {
246 int min = 0;
247 clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
248 clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
249 clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
250}
251
252void mixedSignedness12(int a) {
253 int min = 0;
254 clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
255 clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
256 clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
257}
258
259void mixedSignedness13(int a) {
260 unsigned max = INT_MAX;
261 clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
262 clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
263 clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
264}
265
266void mixedSignedness14(int a) {
267 unsigned max = INT_MAX;
268 clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}}
269 clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}}
270 clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}}
271}
272
273void mixedSignedness15(int a) {
274 unsigned min = INT_MIN;
275 clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
276 clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
277 clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}}
278}
279
280void mixedSignedness16(int a) {
281 unsigned min = INT_MIN;
282 clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
283 clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
284 clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
285}
286
287void mixedSignedness17(int a) {
288 unsigned max = INT_MAX;
289 if (a < max)
290 return;
291
292 clang_analyzer_eval(a < 0); // expected-warning{{UNKNOWN}}
293 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
294 clang_analyzer_eval(a == INT_MAX); // expected-warning{{UNKNOWN}}
295}
296
297void mixedSignedness18(int a) {
298 if (a >= 0)
299 return;
300
301 clang_analyzer_eval(a < 0); // expected-warning{{TRUE}}
302 clang_analyzer_eval(a == (unsigned)INT_MIN); // expected-warning{{UNKNOWN}}
303 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
304}