1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
2
3 #define UINT_MAX (~0U)
4 #define INT_MAX (int)(UINT_MAX & (UINT_MAX >> 1))
5 #define INT_MIN (int)(UINT_MAX & ~(UINT_MAX >> 1))
6
7 void clang_analyzer_eval(int);
8
9 // There should be no warnings unless otherwise indicated.
10
testComparisons(int a)11 void testComparisons (int a) {
12 // Sema can already catch the simple comparison a==a,
13 // since that's usually a logic error (and not path-dependent).
14 int b = a;
15 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
16 clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
17 clang_analyzer_eval(b <= a); // expected-warning{{TRUE}}
18 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
19 clang_analyzer_eval(b > a); // expected-warning{{FALSE}}
20 clang_analyzer_eval(b < a); // expected-warning{{FALSE}}
21 }
22
testSelfOperations(int a)23 void testSelfOperations (int a) {
24 clang_analyzer_eval((a|a) == a); // expected-warning{{TRUE}}
25 clang_analyzer_eval((a&a) == a); // expected-warning{{TRUE}}
26 clang_analyzer_eval((a^a) == 0); // expected-warning{{TRUE}}
27 clang_analyzer_eval((a-a) == 0); // expected-warning{{TRUE}}
28 }
29
testIdempotent(int a)30 void testIdempotent (int a) {
31 clang_analyzer_eval((a*1) == a); // expected-warning{{TRUE}}
32 clang_analyzer_eval((a/1) == a); // expected-warning{{TRUE}}
33 clang_analyzer_eval((a+0) == a); // expected-warning{{TRUE}}
34 clang_analyzer_eval((a-0) == a); // expected-warning{{TRUE}}
35 clang_analyzer_eval((a<<0) == a); // expected-warning{{TRUE}}
36 clang_analyzer_eval((a>>0) == a); // expected-warning{{TRUE}}
37 clang_analyzer_eval((a^0) == a); // expected-warning{{TRUE}}
38 clang_analyzer_eval((a&(~0)) == a); // expected-warning{{TRUE}}
39 clang_analyzer_eval((a|0) == a); // expected-warning{{TRUE}}
40 }
41
testReductionToConstant(int a)42 void testReductionToConstant (int a) {
43 clang_analyzer_eval((a*0) == 0); // expected-warning{{TRUE}}
44 clang_analyzer_eval((a&0) == 0); // expected-warning{{TRUE}}
45 clang_analyzer_eval((a|(~0)) == (~0)); // expected-warning{{TRUE}}
46 }
47
testSymmetricIntSymOperations(int a)48 void testSymmetricIntSymOperations (int a) {
49 clang_analyzer_eval((2+a) == (a+2)); // expected-warning{{TRUE}}
50 clang_analyzer_eval((2*a) == (a*2)); // expected-warning{{TRUE}}
51 clang_analyzer_eval((2&a) == (a&2)); // expected-warning{{TRUE}}
52 clang_analyzer_eval((2^a) == (a^2)); // expected-warning{{TRUE}}
53 clang_analyzer_eval((2|a) == (a|2)); // expected-warning{{TRUE}}
54 }
55
testAsymmetricIntSymOperations(int a)56 void testAsymmetricIntSymOperations (int a) {
57 clang_analyzer_eval(((~0) >> a) == (~0)); // expected-warning{{TRUE}}
58 clang_analyzer_eval((0 >> a) == 0); // expected-warning{{TRUE}}
59 clang_analyzer_eval((0 << a) == 0); // expected-warning{{TRUE}}
60
61 // Unsigned right shift shifts in zeroes.
62 clang_analyzer_eval(((~0U) >> a) != (~0U)); // expected-warning{{UNKNOWN}}
63 }
64
testLocations(char * a)65 void testLocations (char *a) {
66 char *b = a;
67 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
68 clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
69 clang_analyzer_eval(b <= a); // expected-warning{{TRUE}}
70 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
71 clang_analyzer_eval(b > a); // expected-warning{{FALSE}}
72 clang_analyzer_eval(b < a); // expected-warning{{FALSE}}
73 }
74
testMixedTypeComparisons(char a,unsigned long b)75 void testMixedTypeComparisons (char a, unsigned long b) {
76 if (a != 0) return;
77 if (b != 0x100) return;
78
79 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
80 clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
81 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
82 }
83
testBitwiseRules(unsigned int a,int b,int c)84 void testBitwiseRules(unsigned int a, int b, int c) {
85 clang_analyzer_eval((a | 1) >= 1); // expected-warning{{TRUE}}
86 clang_analyzer_eval((a | -1) >= -1); // expected-warning{{TRUE}}
87 clang_analyzer_eval((a | 2) >= 2); // expected-warning{{TRUE}}
88 clang_analyzer_eval((a | 5) >= 5); // expected-warning{{TRUE}}
89 clang_analyzer_eval((a | 10) >= 10); // expected-warning{{TRUE}}
90
91 // Argument order should not influence this
92 clang_analyzer_eval((1 | a) >= 1); // expected-warning{{TRUE}}
93
94 clang_analyzer_eval((a & 1) <= 1); // expected-warning{{TRUE}}
95 clang_analyzer_eval((a & 1) >= 0); // expected-warning{{TRUE}}
96 clang_analyzer_eval((a & 2) <= 2); // expected-warning{{TRUE}}
97 clang_analyzer_eval((a & 5) <= 5); // expected-warning{{TRUE}}
98 clang_analyzer_eval((a & 10) <= 10); // expected-warning{{TRUE}}
99 clang_analyzer_eval((a & -10) <= 10); // expected-warning{{UNKNOWN}}
100
101 // Again, check for different argument order.
102 clang_analyzer_eval((1 & a) <= 1); // expected-warning{{TRUE}}
103
104 unsigned int d = a;
105 d |= 1;
106 clang_analyzer_eval((d | 0) == 0); // expected-warning{{FALSE}}
107
108 // Rules don't apply to signed typed, as the values might be negative.
109 clang_analyzer_eval((b | 1) > 0); // expected-warning{{UNKNOWN}}
110
111 // Even for signed values, bitwise OR with a non-zero is always non-zero.
112 clang_analyzer_eval((b | 1) == 0); // expected-warning{{FALSE}}
113 clang_analyzer_eval((b | -2) == 0); // expected-warning{{FALSE}}
114 clang_analyzer_eval((b | 10) == 0); // expected-warning{{FALSE}}
115 clang_analyzer_eval((b | 0) == 0); // expected-warning{{UNKNOWN}}
116 clang_analyzer_eval((b | -2) >= 0); // expected-warning{{FALSE}}
117
118 // Check that we can operate with negative ranges
119 if (b < 0) {
120 clang_analyzer_eval((b | -1) == -1); // expected-warning{{TRUE}}
121 clang_analyzer_eval((b | -10) >= -10); // expected-warning{{TRUE}}
122 clang_analyzer_eval((b & 0) == 0); // expected-warning{{TRUE}}
123 clang_analyzer_eval((b & -10) <= -10); // expected-warning{{TRUE}}
124 clang_analyzer_eval((b & 5) >= 0); // expected-warning{{TRUE}}
125
126 int e = (b | -5);
127 clang_analyzer_eval(e >= -5 && e <= -1); // expected-warning{{TRUE}}
128
129 if (b < -20) {
130 clang_analyzer_eval((b | e) >= -5); // expected-warning{{TRUE}}
131 clang_analyzer_eval((b & -10) < -20); // expected-warning{{TRUE}}
132 clang_analyzer_eval((b & e) < -20); // expected-warning{{TRUE}}
133 clang_analyzer_eval((b & -30) <= -30); // expected-warning{{TRUE}}
134
135 if (c >= -30 && c <= -10) {
136 clang_analyzer_eval((b & c) <= -20); // expected-warning{{TRUE}}
137 }
138 }
139
140 if (a <= 40) {
141 int g = (int)a & b;
142 clang_analyzer_eval(g <= 40 && g >= 0); // expected-warning{{TRUE}}
143 }
144
145 // Check that we can reason about the result even if know nothing
146 // about one of the operands.
147 clang_analyzer_eval((b | c) != 0); // expected-warning{{TRUE}}
148 }
149
150 if (a <= 30 && b >= 10 && c >= 20) {
151 // Check that we can reason about non-constant operands.
152 clang_analyzer_eval((b | c) >= 20); // expected-warning{{TRUE}}
153
154 // Check that we can reason about the resulting range even if
155 // the types are not the same, but we still can convert operand
156 // ranges.
157 clang_analyzer_eval((a | b) >= 10); // expected-warning{{TRUE}}
158 clang_analyzer_eval((a & b) <= 30); // expected-warning{{TRUE}}
159
160 if (b <= 20) {
161 clang_analyzer_eval((a & b) <= 20); // expected-warning{{TRUE}}
162 }
163 }
164
165 // Check that dynamically computed constants also work.
166 unsigned int constant = 1 << 3;
167 unsigned int f = a | constant;
168 clang_analyzer_eval(f >= constant); // expected-warning{{TRUE}}
169
170 // Check that nested expressions also work.
171 clang_analyzer_eval(((a | 10) | 5) >= 10); // expected-warning{{TRUE}}
172
173 if (a < 10) {
174 clang_analyzer_eval((a | 20) >= 20); // expected-warning{{TRUE}}
175 }
176
177 if (a > 10) {
178 clang_analyzer_eval((a & 1) <= 1); // expected-warning{{TRUE}}
179 }
180 }
181
182 unsigned reset(void);
183
testCombinedSources(unsigned a,unsigned b)184 void testCombinedSources(unsigned a, unsigned b) {
185 if (b >= 10 && (a | b) <= 30) {
186 // Check that we can merge constraints from (a | b), a, and b.
187 // Because of the order of assumptions, we already know that (a | b) is [10, 30].
188 clang_analyzer_eval((a | b) >= 10 && (a | b) <= 30); // expected-warning{{TRUE}}
189 }
190
191 a = reset();
192 b = reset();
193
194 if ((a | b) <= 30 && b >= 10) {
195 // Check that we can merge constraints from (a | b), a, and b.
196 // At this point, we know that (a | b) is [0, 30], but the knowledge
197 // of b >= 10 added later can help us to refine it and change it to [10, 30].
198 clang_analyzer_eval(10 <= (a | b) && (a | b) <= 30); // expected-warning{{TRUE}}
199 }
200
201 a = reset();
202 b = reset();
203
204 unsigned c = (a | b) & (a != b);
205 if (c <= 40 && a == b) {
206 // Even though we have a directo constraint for c [0, 40],
207 // we can get a more precise range by looking at the expression itself.
208 clang_analyzer_eval(c == 0); // expected-warning{{TRUE}}
209 }
210 }
211
testRemainderRules(unsigned int a,unsigned int b,int c,int d)212 void testRemainderRules(unsigned int a, unsigned int b, int c, int d) {
213 // Check that we know that remainder of zero divided by any number is still 0.
214 clang_analyzer_eval((0 % c) == 0); // expected-warning{{TRUE}}
215
216 clang_analyzer_eval((10 % a) <= 10); // expected-warning{{TRUE}}
217
218 if (a <= 30 && b <= 50) {
219 clang_analyzer_eval((40 % a) < 30); // expected-warning{{TRUE}}
220 clang_analyzer_eval((a % b) < 50); // expected-warning{{TRUE}}
221 clang_analyzer_eval((b % a) < 30); // expected-warning{{TRUE}}
222
223 if (a >= 10) {
224 // Even though it seems like a valid assumption, it is not.
225 // Check that we are not making this mistake.
226 clang_analyzer_eval((a % b) >= 10); // expected-warning{{UNKNOWN}}
227
228 // Check that we can we can infer when remainder is equal
229 // to the dividend.
230 clang_analyzer_eval((4 % a) == 4); // expected-warning{{TRUE}}
231 if (b < 7) {
232 clang_analyzer_eval((b % a) < 7); // expected-warning{{TRUE}}
233 }
234 }
235 }
236
237 if (c > -10) {
238 clang_analyzer_eval((d % c) < INT_MAX); // expected-warning{{TRUE}}
239 clang_analyzer_eval((d % c) > INT_MIN + 1); // expected-warning{{TRUE}}
240 }
241
242 // Check that we can reason about signed integers when they are
243 // known to be positive.
244 if (c >= 10 && c <= 30 && d >= 20 && d <= 50) {
245 clang_analyzer_eval((5 % c) == 5); // expected-warning{{TRUE}}
246 clang_analyzer_eval((c % d) <= 30); // expected-warning{{TRUE}}
247 clang_analyzer_eval((c % d) >= 0); // expected-warning{{TRUE}}
248 clang_analyzer_eval((d % c) < 30); // expected-warning{{TRUE}}
249 clang_analyzer_eval((d % c) >= 0); // expected-warning{{TRUE}}
250 }
251
252 if (c >= -30 && c <= -10 && d >= -20 && d <= 50) {
253 // Test positive LHS with negative RHS.
254 clang_analyzer_eval((40 % c) < 30); // expected-warning{{TRUE}}
255 clang_analyzer_eval((40 % c) > -30); // expected-warning{{TRUE}}
256
257 // Test negative LHS with possibly negative RHS.
258 clang_analyzer_eval((-10 % d) < 50); // expected-warning{{TRUE}}
259 clang_analyzer_eval((-20 % d) > -50); // expected-warning{{TRUE}}
260
261 // Check that we don't make wrong assumptions
262 clang_analyzer_eval((-20 % d) > -20); // expected-warning{{UNKNOWN}}
263
264 // Check that we can reason about negative ranges...
265 clang_analyzer_eval((c % d) < 50); // expected-warning{{TRUE}}
266 /// ...both ways
267 clang_analyzer_eval((d % c) < 30); // expected-warning{{TRUE}}
268
269 if (a <= 10) {
270 // Result is unsigned. This means that 'c' is casted to unsigned.
271 // We don't want to reason about ranges changing boundaries with
272 // conversions.
273 clang_analyzer_eval((a % c) < 30); // expected-warning{{UNKNOWN}}
274 }
275 }
276
277 // Check that we work correctly when minimal unsigned value from a range is
278 // equal to the signed minimum for the same bit width.
279 unsigned int x = INT_MIN;
280 if (a >= x && a <= x + 10) {
281 clang_analyzer_eval((b % a) < x + 10); // expected-warning{{TRUE}}
282 }
283 }
284
testDisequalityRules(unsigned int u1,unsigned int u2,unsigned int u3,int s1,int s2,int s3,unsigned char uch,signed char sch,short ssh,unsigned short ush)285 void testDisequalityRules(unsigned int u1, unsigned int u2, unsigned int u3,
286 int s1, int s2, int s3, unsigned char uch,
287 signed char sch, short ssh, unsigned short ush) {
288
289 // Checks for overflowing values
290 if (u1 > INT_MAX && u1 <= UINT_MAX / 2 + 4 && u1 != UINT_MAX / 2 + 2 &&
291 u1 != UINT_MAX / 2 + 3 && s1 >= INT_MIN + 1 && s1 <= INT_MIN + 2) {
292 // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4],
293 // s1: [INT_MIN+1, INT_MIN+2]
294 clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
295 }
296
297 if (u1 >= INT_MIN && u1 <= INT_MIN + 2 &&
298 s1 > INT_MIN + 2 && s1 < INT_MIN + 4) {
299 // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4],
300 // s1: [INT_MIN+3, INT_MIN+3]
301 clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
302 }
303
304 if (s1 < 0 && s1 > -4 && u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) {
305 // s1: [-3, -1], u1: [UINT_MAX - 3, UINT_MAX - 2]
306 clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
307 clang_analyzer_eval(s1 != u1); // expected-warning{{TRUE}}
308 }
309
310 if (s1 < 1 && s1 > -6 && s1 != -4 && s1 != -3 &&
311 u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) {
312 // s1: [-5, -5]U[-2, 0], u1: [UINT_MAX - 3, UINT_MAX - 2]
313 clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
314 }
315
316 if (s1 < 1 && s1 > -7 && s1 != -4 && s1 != -3 &&
317 u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) {
318 // s1: [-6, -5]U[-2, 0], u1: [UINT_MAX - 3, UINT_MAX - 2]
319 clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
320 }
321
322 if (s1 > 4 && u1 < 4) {
323 // s1: [4, INT_MAX], u1: [0, 3]
324 clang_analyzer_eval(s1 != u1); // expected-warning{{TRUE}}
325 }
326
327 // Check when RHS is in between two Ranges in LHS
328 if (((u1 >= 1 && u1 <= 2) || (u1 >= 8 && u1 <= 9)) &&
329 u2 >= 5 && u2 <= 6) {
330 // u1: [1, 2]U[8, 9], u2: [5, 6]
331 clang_analyzer_eval(u1 != u2); // expected-warning{{TRUE}}
332 }
333
334 // Checks for concrete value with same type
335 if (u1 > 1 && u1 < 3 && u2 > 1 && u2 < 3) {
336 // u1: [2, 2], u2: [2, 2]
337 clang_analyzer_eval(u1 != u2); // expected-warning{{FALSE}}
338 }
339
340 // Check for concrete value with different types
341 if (u1 > 4 && u1 < 6 && s1 > 4 && s1 < 6) {
342 // u1: [5, 5], s1: [5, 5]
343 clang_analyzer_eval(u1 != s1); // expected-warning{{FALSE}}
344 }
345
346 // Checks when ranges are not overlapping
347 if (u1 <= 10 && u2 >= 20) {
348 // u1: [0,10], u2: [20,UINT_MAX]
349 clang_analyzer_eval(u1 != u2); // expected-warning{{TRUE}}
350 }
351
352 if (s1 <= INT_MIN + 10 && s2 >= INT_MAX - 10) {
353 // s1: [INT_MIN,INT_MIN + 10], s2: [INT_MAX - 10,INT_MAX]
354 clang_analyzer_eval(s1 != s2); // expected-warning{{TRUE}}
355 }
356
357 // Checks when ranges are completely overlapping and have more than one point
358 if (u1 >= 20 && u1 <= 50 && u2 >= 20 && u2 <= 50) {
359 // u1: [20,50], u2: [20,50]
360 clang_analyzer_eval(u1 != u2); // expected-warning{{UNKNOWN}}
361 }
362
363 if (s1 >= -20 && s1 <= 20 && s2 >= -20 && s2 <= 20) {
364 // s1: [-20,20], s2: [-20,20]
365 clang_analyzer_eval(s1 != s2); // expected-warning{{UNKNOWN}}
366 }
367
368 // Checks when ranges are partially overlapping
369 if (u1 >= 100 && u1 <= 200 && u2 >= 150 && u2 <= 300) {
370 // u1: [100,200], u2: [150,300]
371 clang_analyzer_eval(u1 != u2); // expected-warning{{UNKNOWN}}
372 }
373
374 if (s1 >= -80 && s1 <= -50 && s2 >= -100 && s2 <= -75) {
375 // s1: [-80,-50], s2: [-100,-75]
376 clang_analyzer_eval(s1 != s2); // expected-warning{{UNKNOWN}}
377 }
378
379 // Checks for ranges which are subset of one-another
380 if (u1 >= 500 && u1 <= 1000 && u2 >= 750 && u2 <= 1000) {
381 // u1: [500,1000], u2: [750,1000]
382 clang_analyzer_eval(u1 != u2); // expected-warning{{UNKNOWN}}
383 }
384
385 if (s1 >= -1000 && s1 <= -500 && s2 >= -750 && s2 <= -500) {
386 // s1: [-1000,-500], s2: [-750, -500]
387 clang_analyzer_eval(s1 != s2); // expected-warning{{UNKNOWN}}
388 }
389
390 // Checks for comparison between different types
391 // Using different variables as previous constraints may interfere in the
392 // reasoning.
393 if (u3 <= 255 && s3 < 0) {
394 // u3: [0, 255], s3: [INT_MIN, -1]
395 clang_analyzer_eval(u3 != s3); // expected-warning{{TRUE}}
396 }
397
398 // Checks for char-uchar types
399 if (uch >= 1 && sch <= 1) {
400 // uch: [1, UCHAR_MAX], sch: [SCHAR_MIN, 1]
401 clang_analyzer_eval(uch != sch); // expected-warning{{UNKNOWN}}
402 }
403
404 if (uch > 1 && sch < 1) {
405 // uch: [2, UCHAR_MAX], sch: [SCHAR_MIN, 0]
406 clang_analyzer_eval(uch != sch); // expected-warning{{TRUE}}
407 clang_analyzer_eval(sch != uch); // expected-warning{{TRUE}}
408 }
409
410 if (uch <= 1 && uch >= 1 && sch <= 1 && sch >= 1) {
411 // uch: [1, 1], sch: [1, 1]
412 clang_analyzer_eval(uch != sch); // expected-warning{{FALSE}}
413 }
414
415 // Checks for short-ushort types
416 if (ush >= 1 && ssh <= 1) {
417 // ush: [1, USHRT_MAX], ssh: [SHRT_MIN, 1]
418 clang_analyzer_eval(ush != ssh); // expected-warning{{UNKNOWN}}
419 }
420
421 if (ush > 1 && ssh < 1) {
422 // ush: [2, USHRT_MAX], ssh: [SHRT_MIN, 0]
423 clang_analyzer_eval(ush != ssh); // expected-warning{{TRUE}}
424 }
425
426 if (ush <= 1 && ush >= 1 && ssh <= 1 && ssh >= 1) {
427 // ush: [1, 1], ssh: [1, 1]
428 clang_analyzer_eval(ush != ssh); // expected-warning{{FALSE}}
429 }
430 }
431