Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / equality_tracking.c
blobe33b95700d0024e5152ad355d06c6a832ae9a52e
1 // RUN: %clang_analyze_cc1 -verify %s \
2 // RUN: -analyzer-checker=core,debug.ExprInspection \
3 // RUN: -analyzer-config eagerly-assume=false
5 #define NULL (void *)0
7 #define UCHAR_MAX (unsigned char)(~0U)
8 #define CHAR_MAX (char)(UCHAR_MAX & (UCHAR_MAX >> 1))
9 #define CHAR_MIN (char)(UCHAR_MAX & ~(UCHAR_MAX >> 1))
11 void clang_analyzer_value(int);
12 void clang_analyzer_eval(int);
13 void clang_analyzer_warnIfReached(void);
15 int getInt(void);
17 void zeroImpliesEquality(int a, int b) {
18 clang_analyzer_eval((a - b) == 0); // expected-warning{{UNKNOWN}}
19 if ((a - b) == 0) {
20 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
21 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
22 clang_analyzer_eval(!(a != b)); // expected-warning{{TRUE}}
23 clang_analyzer_eval(!(b == a)); // expected-warning{{FALSE}}
24 return;
26 clang_analyzer_eval((a - b) == 0); // expected-warning{{FALSE}}
27 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}
28 clang_analyzer_eval(b != a); // expected-warning{{TRUE}}
31 void zeroImpliesReversedEqual(int a, int b) {
32 clang_analyzer_eval((b - a) == 0); // expected-warning{{UNKNOWN}}
33 if ((b - a) == 0) {
34 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
35 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
36 return;
38 clang_analyzer_eval((b - a) == 0); // expected-warning{{FALSE}}
39 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}
40 clang_analyzer_eval(b != a); // expected-warning{{TRUE}}
43 void canonicalEqual(int a, int b) {
44 clang_analyzer_eval(a == b); // expected-warning{{UNKNOWN}}
45 if (a == b) {
46 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
47 return;
49 clang_analyzer_eval(a == b); // expected-warning{{FALSE}}
50 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}
53 void test(int a, int b, int c, int d) {
54 if (a == b && c == d) {
55 if (a == 0 && b == d) {
56 clang_analyzer_eval(c == 0); // expected-warning{{TRUE}}
58 c = 10;
59 if (b == d) {
60 clang_analyzer_eval(c == 10); // expected-warning{{TRUE}}
61 clang_analyzer_eval(d == 10); // expected-warning{{UNKNOWN}}
62 // expected-warning@-1{{FALSE}}
63 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
64 clang_analyzer_eval(a == d); // expected-warning{{TRUE}}
66 b = getInt();
67 clang_analyzer_eval(a == d); // expected-warning{{TRUE}}
68 clang_analyzer_eval(a == b); // expected-warning{{UNKNOWN}}
72 if (a != b && b == c) {
73 if (c == 42) {
74 clang_analyzer_eval(b == 42); // expected-warning{{TRUE}}
75 clang_analyzer_eval(a != 42); // expected-warning{{TRUE}}
80 void testIntersection(int a, int b, int c) {
81 if (a < 42 && b > 15 && c >= 25 && c <= 30) {
82 if (a != b)
83 return;
85 clang_analyzer_eval(a > 15); // expected-warning{{TRUE}}
86 clang_analyzer_eval(b < 42); // expected-warning{{TRUE}}
87 clang_analyzer_eval(a <= 30); // expected-warning{{UNKNOWN}}
89 if (c == b) {
90 // For all equal symbols, we should track the minimal common range.
92 // Also, it should be noted that c is dead at this point, but the
93 // constraint initially associated with c is still around.
94 clang_analyzer_eval(a >= 25 && a <= 30); // expected-warning{{TRUE}}
95 clang_analyzer_eval(b >= 25 && b <= 30); // expected-warning{{TRUE}}
100 void testPromotion(int a, char b) {
101 if (b > 10) {
102 if (a == b) {
103 // FIXME: support transferring char ranges onto equal int symbols
104 // when char is promoted to int
105 clang_analyzer_eval(a > 10); // expected-warning{{UNKNOWN}}
106 clang_analyzer_eval(a <= CHAR_MAX); // expected-warning{{UNKNOWN}}
111 void testPromotionOnlyTypes(int a, char b) {
112 if (a == b) {
113 // FIXME: support transferring char ranges onto equal int symbols
114 // when char is promoted to int
115 clang_analyzer_eval(a <= CHAR_MAX); // expected-warning{{UNKNOWN}}
119 void testDowncast(int a, unsigned char b) {
120 if (a <= -10) {
121 if ((unsigned char)a == b) {
122 // Even though ranges for a and b do not intersect,
123 // ranges for (unsigned char)a and b do.
124 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
126 if (a == b) {
127 // FIXME: This case on the other hand is different, it shouldn't be
128 // reachable. However, the corrent symbolic information available
129 // to the solver doesn't allow it to distinguish this expression
130 // from the previous one.
131 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
136 void testPointers(int *a, int *b, int *c, int *d) {
137 if (a == b && c == d) {
138 if (a == NULL && b == d) {
139 clang_analyzer_eval(c == NULL); // expected-warning{{TRUE}}
143 if (a != b && b == c) {
144 if (c == NULL) {
145 clang_analyzer_eval(a != NULL); // expected-warning{{TRUE}}
150 void testDisequalitiesAfter(int a, int b, int c) {
151 if (a >= 10 && b <= 42) {
152 if (a == b && c == 15 && c != a) {
153 clang_analyzer_eval(b != c); // expected-warning{{TRUE}}
154 clang_analyzer_eval(a != 15); // expected-warning{{TRUE}}
155 clang_analyzer_eval(b != 15); // expected-warning{{TRUE}}
156 clang_analyzer_eval(b >= 10); // expected-warning{{TRUE}}
157 clang_analyzer_eval(a <= 42); // expected-warning{{TRUE}}
162 void testDisequalitiesBefore(int a, int b, int c) {
163 if (a >= 10 && b <= 42 && c == 15) {
164 if (a == b && c != a) {
165 clang_analyzer_eval(b != c); // expected-warning{{TRUE}}
166 clang_analyzer_eval(a != 15); // expected-warning{{TRUE}}
167 clang_analyzer_eval(b != 15); // expected-warning{{TRUE}}
168 clang_analyzer_eval(b >= 10); // expected-warning{{TRUE}}
169 clang_analyzer_eval(a <= 42); // expected-warning{{TRUE}}
174 void avoidInfeasibleConstraintsForClasses(int a, int b) {
175 if (a >= 0 && a <= 10 && b >= 20 && b <= 50) {
176 if ((b - a) == 0) {
177 clang_analyzer_warnIfReached(); // no warning
179 if (a == b) {
180 clang_analyzer_warnIfReached(); // no warning
182 if (a != b) {
183 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
184 } else {
185 clang_analyzer_warnIfReached(); // no warning
190 void avoidInfeasibleConstraintforGT(int a, int b) {
191 int c = b - a;
192 if (c <= 0)
193 return;
194 // c > 0
195 // b - a > 0
196 // b > a
197 if (a != b) {
198 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
199 return;
201 clang_analyzer_warnIfReached(); // no warning
202 // a == b
203 if (c < 0)
207 void avoidInfeasibleConstraintforLT(int a, int b) {
208 int c = b - a;
209 if (c >= 0)
210 return;
211 // c < 0
212 // b - a < 0
213 // b < a
214 if (a != b) {
215 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
216 return;
218 clang_analyzer_warnIfReached(); // no warning
219 // a == b
220 if (c < 0)
224 void implyDisequalityFromGT(int a, int b) {
225 if (a > b) {
226 clang_analyzer_eval(a == b); // expected-warning{{FALSE}}
227 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
231 void implyDisequalityFromLT(int a, int b) {
232 if (a < b) {
233 clang_analyzer_eval(a == b); // expected-warning{{FALSE}}
234 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
238 void deletePointBefore(int x, int tmp) {
239 if(tmp == 0)
240 if(x != tmp)
241 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, -1], [1, 2147483647] }}}
244 void deletePointAfter(int x, int tmp) {
245 if(x != tmp)
246 if(tmp == 2147483647)
247 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, 2147483646] }}}
250 void deleteTwoPoints(int x, int tmp1, int tmp2) {
251 if(x != tmp1) {
252 if (tmp1 == 42 && tmp2 == 87) {
253 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, 41], [43, 2147483647] }}}
254 if(x != tmp2)
255 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, 41], [43, 86], [88, 2147483647] }}}
260 void deleteAllPoints(unsigned char x, unsigned char *arr) {
262 #define cond(n) \
263 arr[n##0] == n##0 && \
264 arr[n##1] == n##1 && \
265 arr[n##2] == n##2 && \
266 arr[n##3] == n##3 && \
267 arr[n##4] == n##4 && \
268 arr[n##5] == n##5 && \
269 arr[n##6] == n##6 && \
270 arr[n##7] == n##7 && \
271 arr[n##8] == n##8 && \
272 arr[n##9] == n##9 && \
274 #define condX(n) \
275 arr[n##0] != x && \
276 arr[n##1] != x && \
277 arr[n##2] != x && \
278 arr[n##3] != x && \
279 arr[n##4] != x && \
280 arr[n##5] != x && \
281 arr[n##6] != x && \
282 arr[n##7] != x && \
283 arr[n##8] != x && \
284 arr[n##9] != x && \
286 clang_analyzer_value(x); // expected-warning {{{ [0, 255] }}}
287 if (
288 cond() // 0 .. 9
289 cond(1) // 10 .. 19
290 cond(2) // 20 .. 29
291 cond(3) // 30 .. 39
292 cond(4) // 40 .. 49
293 cond(5) // 50 .. 59
294 cond(6) // 60 .. 69
295 cond(7) // 70 .. 79
296 cond(8) // 80 .. 89
297 cond(9) // 90 .. 99
298 cond(10) // 100 .. 209
299 cond(11) // 110 .. 219
300 cond(12) // 120 .. 229
301 cond(13) // 130 .. 239
302 cond(14) // 140 .. 249
303 cond(15) // 150 .. 259
304 cond(16) // 160 .. 269
305 cond(17) // 170 .. 279
306 cond(18) // 180 .. 289
307 cond(19) // 190 .. 199
308 cond(20) // 200 .. 209
309 cond(21) // 210 .. 219
310 cond(22) // 220 .. 229
311 cond(23) // 230 .. 239
312 cond(24) // 240 .. 249
313 arr[250] == 250 &&
314 arr[251] == 251 &&
315 arr[252] == 252 &&
316 arr[253] == 253 &&
317 arr[254] == 254 &&
318 arr[255] == 255
320 if (
321 condX() // 0 .. 9
322 condX(1) // 10 .. 19
323 condX(2) // 20 .. 29
324 condX(3) // 30 .. 39
325 condX(4) // 40 .. 49
326 condX(5) // 50 .. 59
327 condX(6) // 60 .. 69
328 condX(7) // 70 .. 79
329 condX(8) // 80 .. 89
330 condX(9) // 90 .. 99
331 condX(10) // 100 .. 209
332 condX(11) // 110 .. 219
333 condX(12) // 120 .. 229
334 condX(13) // 130 .. 239
335 condX(14) // 140 .. 249
336 condX(15) // 150 .. 259
337 condX(16) // 160 .. 269
338 condX(17) // 170 .. 279
339 condX(18) // 180 .. 289
340 condX(19) // 190 .. 199
341 condX(20) // 200 .. 209
342 condX(21) // 210 .. 219
343 condX(22) // 220 .. 229
344 condX(23) // 230 .. 239
345 arr[240] != x &&
346 arr[241] != x &&
347 arr[242] != x &&
348 arr[243] != x &&
349 arr[244] != x &&
350 arr[245] != x &&
351 arr[246] != x &&
352 arr[247] != x &&
353 arr[248] != x &&
354 arr[249] != x
356 clang_analyzer_value(x); // expected-warning {{{ [250, 255] }}}
357 if (
358 arr[250] != x &&
359 arr[251] != x &&
360 //skip arr[252]
361 arr[253] != x &&
362 arr[254] != x &&
363 arr[255] != x
365 clang_analyzer_value(x); // expected-warning {{32s:252}}
366 if (arr[252] != x) {
367 clang_analyzer_warnIfReached(); // unreachable