xref: /llvm-project/clang/test/Analysis/constant-folding.c (revision 5f02ad880e423a33f903299f0123e9d8a59bbe8d)
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