1 // RUN: %clang_analyze_cc1 -verify %s \
2 // RUN: -analyzer-checker=core,debug.ExprInspection \
3 // RUN: -analyzer-config eagerly-assume=false
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);
17 void zeroImpliesEquality(int a
, int b
) {
18 clang_analyzer_eval((a
- b
) == 0); // expected-warning{{UNKNOWN}}
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}}
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}}
34 clang_analyzer_eval(b
!= a
); // expected-warning{{FALSE}}
35 clang_analyzer_eval(b
== a
); // expected-warning{{TRUE}}
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}}
46 clang_analyzer_eval(b
== a
); // expected-warning{{TRUE}}
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}}
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}}
67 clang_analyzer_eval(a
== d
); // expected-warning{{TRUE}}
68 clang_analyzer_eval(a
== b
); // expected-warning{{UNKNOWN}}
72 if (a
!= b
&& b
== c
) {
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) {
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}}
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
) {
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
) {
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
) {
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}}
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
) {
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) {
177 clang_analyzer_warnIfReached(); // no warning
180 clang_analyzer_warnIfReached(); // no warning
183 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
185 clang_analyzer_warnIfReached(); // no warning
190 void avoidInfeasibleConstraintforGT(int a
, int b
) {
198 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
201 clang_analyzer_warnIfReached(); // no warning
207 void avoidInfeasibleConstraintforLT(int a
, int b
) {
215 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
218 clang_analyzer_warnIfReached(); // no warning
224 void implyDisequalityFromGT(int a
, int 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
) {
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
) {
241 clang_analyzer_value(x
); // expected-warning {{32s:{ [-2147483648, -1], [1, 2147483647] }}}
244 void deletePointAfter(int x
, int tmp
) {
246 if(tmp
== 2147483647)
247 clang_analyzer_value(x
); // expected-warning {{32s:{ [-2147483648, 2147483646] }}}
250 void deleteTwoPoints(int x
, int tmp1
, int tmp2
) {
252 if (tmp1
== 42 && tmp2
== 87) {
253 clang_analyzer_value(x
); // expected-warning {{32s:{ [-2147483648, 41], [43, 2147483647] }}}
255 clang_analyzer_value(x
); // expected-warning {{32s:{ [-2147483648, 41], [43, 86], [88, 2147483647] }}}
260 void deleteAllPoints(unsigned char x
, unsigned char *arr
) {
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 && \
286 clang_analyzer_value(x); // expected-warning {{{ [0, 255] }}}
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
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
356 clang_analyzer_value(x
); // expected-warning {{{ [250, 255] }}}
365 clang_analyzer_value(x
); // expected-warning {{32s:252}}
367 clang_analyzer_warnIfReached(); // unreachable