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 
testRemainderRules(unsigned int a,unsigned int b,int c,int d)182 void testRemainderRules(unsigned int a, unsigned int b, int c, int d) {
183   // Check that we know that remainder of zero divided by any number is still 0.
184   clang_analyzer_eval((0 % c) == 0); // expected-warning{{TRUE}}
185 
186   clang_analyzer_eval((10 % a) <= 10); // expected-warning{{TRUE}}
187 
188   if (a <= 30 && b <= 50) {
189     clang_analyzer_eval((40 % a) < 30); // expected-warning{{TRUE}}
190     clang_analyzer_eval((a % b) < 50);  // expected-warning{{TRUE}}
191     clang_analyzer_eval((b % a) < 30);  // expected-warning{{TRUE}}
192 
193     if (a >= 10) {
194       // Even though it seems like a valid assumption, it is not.
195       // Check that we are not making this mistake.
196       clang_analyzer_eval((a % b) >= 10); // expected-warning{{UNKNOWN}}
197 
198       // Check that we can we can infer when remainder is equal
199       // to the dividend.
200       clang_analyzer_eval((4 % a) == 4); // expected-warning{{TRUE}}
201       if (b < 7) {
202         clang_analyzer_eval((b % a) < 7); // expected-warning{{TRUE}}
203       }
204     }
205   }
206 
207   if (c > -10) {
208     clang_analyzer_eval((d % c) < INT_MAX);     // expected-warning{{TRUE}}
209     clang_analyzer_eval((d % c) > INT_MIN + 1); // expected-warning{{TRUE}}
210   }
211 
212   // Check that we can reason about signed integers when they are
213   // known to be positive.
214   if (c >= 10 && c <= 30 && d >= 20 && d <= 50) {
215     clang_analyzer_eval((5 % c) == 5);  // expected-warning{{TRUE}}
216     clang_analyzer_eval((c % d) <= 30); // expected-warning{{TRUE}}
217     clang_analyzer_eval((c % d) >= 0);  // expected-warning{{TRUE}}
218     clang_analyzer_eval((d % c) < 30);  // expected-warning{{TRUE}}
219     clang_analyzer_eval((d % c) >= 0);  // expected-warning{{TRUE}}
220   }
221 
222   if (c >= -30 && c <= -10 && d >= -20 && d <= 50) {
223     // Test positive LHS with negative RHS.
224     clang_analyzer_eval((40 % c) < 30);  // expected-warning{{TRUE}}
225     clang_analyzer_eval((40 % c) > -30); // expected-warning{{TRUE}}
226 
227     // Test negative LHS with possibly negative RHS.
228     clang_analyzer_eval((-10 % d) < 50);  // expected-warning{{TRUE}}
229     clang_analyzer_eval((-20 % d) > -50); // expected-warning{{TRUE}}
230 
231     // Check that we don't make wrong assumptions
232     clang_analyzer_eval((-20 % d) > -20); // expected-warning{{UNKNOWN}}
233 
234     // Check that we can reason about negative ranges...
235     clang_analyzer_eval((c % d) < 50); // expected-warning{{TRUE}}
236     /// ...both ways
237     clang_analyzer_eval((d % c) < 30); // expected-warning{{TRUE}}
238 
239     if (a <= 10) {
240       // Result is unsigned.  This means that 'c' is casted to unsigned.
241       // We don't want to reason about ranges changing boundaries with
242       // conversions.
243       clang_analyzer_eval((a % c) < 30); // expected-warning{{UNKNOWN}}
244     }
245   }
246 
247   // Check that we work correctly when minimal unsigned value from a range is
248   // equal to the signed minimum for the same bit width.
249   unsigned int x = INT_MIN;
250   if (a >= x && a <= x + 10) {
251     clang_analyzer_eval((b % a) < x + 10); // expected-warning{{TRUE}}
252   }
253 }
254