xref: /aosp_15_r20/external/clang/test/Analysis/additive-folding-range-constraints.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range %s
2*67e74705SXin Li 
3*67e74705SXin Li void clang_analyzer_eval(int);
4*67e74705SXin Li 
5*67e74705SXin Li #define UINT_MAX (~0U)
6*67e74705SXin Li #define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
7*67e74705SXin Li #define INT_MIN (-INT_MAX - 1)
8*67e74705SXin Li 
9*67e74705SXin Li 
10*67e74705SXin Li // Each of these adjusted ranges has an adjustment small enough to split the
11*67e74705SXin Li // solution range across an overflow boundary (Min for <, Max for >).
12*67e74705SXin Li // This corresponds to one set of branches in RangeConstraintManager.
smallAdjustmentGT(unsigned a)13*67e74705SXin Li void smallAdjustmentGT (unsigned a) {
14*67e74705SXin Li   if (a+2 > 1)
15*67e74705SXin Li     clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
16*67e74705SXin Li   else
17*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
18*67e74705SXin Li }
19*67e74705SXin Li 
smallAdjustmentGE(unsigned a)20*67e74705SXin Li void smallAdjustmentGE (unsigned a) {
21*67e74705SXin Li   if (a+2 >= 1)
22*67e74705SXin Li     clang_analyzer_eval(a < UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
23*67e74705SXin Li   else
24*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
25*67e74705SXin Li }
26*67e74705SXin Li 
smallAdjustmentLT(unsigned a)27*67e74705SXin Li void smallAdjustmentLT (unsigned a) {
28*67e74705SXin Li   if (a+1 < 2)
29*67e74705SXin Li     clang_analyzer_eval(a == 0 || a == UINT_MAX); // expected-warning{{TRUE}}
30*67e74705SXin Li }
31*67e74705SXin Li 
smallAdjustmentLE(unsigned a)32*67e74705SXin Li void smallAdjustmentLE (unsigned a) {
33*67e74705SXin Li   if (a+1 <= 2)
34*67e74705SXin Li     clang_analyzer_eval(a == 0 || a == 1 || a == UINT_MAX); // expected-warning{{TRUE}}
35*67e74705SXin Li }
36*67e74705SXin Li 
37*67e74705SXin Li 
38*67e74705SXin Li // Each of these adjusted ranges has an adjustment large enough to push the
39*67e74705SXin Li // comparison value over an overflow boundary (Min for <, Max for >).
40*67e74705SXin Li // This corresponds to one set of branches in RangeConstraintManager.
largeAdjustmentGT(unsigned a)41*67e74705SXin Li void largeAdjustmentGT (unsigned a) {
42*67e74705SXin Li   if (a-2 > UINT_MAX-1)
43*67e74705SXin Li     clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
44*67e74705SXin Li   else
45*67e74705SXin Li     clang_analyzer_eval(a != 1); // expected-warning{{TRUE}}
46*67e74705SXin Li }
47*67e74705SXin Li 
largeAdjustmentGE(unsigned a)48*67e74705SXin Li void largeAdjustmentGE (unsigned a) {
49*67e74705SXin Li   if (a-2 >= UINT_MAX-1)
50*67e74705SXin Li     clang_analyzer_eval(a == 1 || a == 0); // expected-warning{{TRUE}}
51*67e74705SXin Li   else
52*67e74705SXin Li     clang_analyzer_eval(a > 1); // expected-warning{{TRUE}}
53*67e74705SXin Li }
54*67e74705SXin Li 
largeAdjustmentLT(unsigned a)55*67e74705SXin Li void largeAdjustmentLT (unsigned a) {
56*67e74705SXin Li   if (a+2 < 1)
57*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
58*67e74705SXin Li   else
59*67e74705SXin Li     clang_analyzer_eval(a != UINT_MAX-1); // expected-warning{{TRUE}}
60*67e74705SXin Li }
61*67e74705SXin Li 
largeAdjustmentLE(unsigned a)62*67e74705SXin Li void largeAdjustmentLE (unsigned a) {
63*67e74705SXin Li   if (a+2 <= 1)
64*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
65*67e74705SXin Li   else
66*67e74705SXin Li     clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
67*67e74705SXin Li }
68*67e74705SXin Li 
69*67e74705SXin Li 
70*67e74705SXin Li // Test the nine cases in RangeConstraintManager's pinning logic.
71*67e74705SXin Li // For out-of-range tautologies, it may be the negation that actually
72*67e74705SXin Li // triggers the case in question.
mixedComparisons1(signed char a)73*67e74705SXin Li void mixedComparisons1(signed char a) {
74*67e74705SXin Li   // Case 1: The range is entirely below the symbol's range.
75*67e74705SXin Li   int min = INT_MIN;
76*67e74705SXin Li 
77*67e74705SXin Li   clang_analyzer_eval((a - 2) >= (min + 5LL)); // expected-warning{{TRUE}}
78*67e74705SXin Li 
79*67e74705SXin Li   clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
80*67e74705SXin Li   clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
81*67e74705SXin Li   clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
82*67e74705SXin Li }
83*67e74705SXin Li 
mixedComparisons2(signed char a)84*67e74705SXin Li void mixedComparisons2(signed char a) {
85*67e74705SXin Li   // Case 2: Only the lower end of the range is outside.
86*67e74705SXin Li   clang_analyzer_eval((a - 5) < (-0x81LL)); // expected-warning{{UNKNOWN}}
87*67e74705SXin Li 
88*67e74705SXin Li   if ((a - 5) < (-0x81LL)) {
89*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
90*67e74705SXin Li     clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
91*67e74705SXin Li     clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
92*67e74705SXin Li   }
93*67e74705SXin Li }
94*67e74705SXin Li 
mixedComparisons3(signed char a)95*67e74705SXin Li void mixedComparisons3(signed char a) {
96*67e74705SXin Li   // Case 3: The entire symbol range is covered.
97*67e74705SXin Li   clang_analyzer_eval((a - 0x200) < -0x100LL); // expected-warning{{TRUE}}
98*67e74705SXin Li 
99*67e74705SXin Li   clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
100*67e74705SXin Li   clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
101*67e74705SXin Li   clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
102*67e74705SXin Li }
103*67e74705SXin Li 
mixedComparisons4(signed char a)104*67e74705SXin Li void mixedComparisons4(signed char a) {
105*67e74705SXin Li   // Case 4: The range wraps around, but the lower wrap is out-of-range.
106*67e74705SXin Li   clang_analyzer_eval((a - 5) > 0LL); // expected-warning{{UNKNOWN}}
107*67e74705SXin Li 
108*67e74705SXin Li   if ((a - 5) > 0LL) {
109*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
110*67e74705SXin Li     clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
111*67e74705SXin Li     clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
112*67e74705SXin Li   }
113*67e74705SXin Li }
114*67e74705SXin Li 
mixedComparisons5(signed char a)115*67e74705SXin Li void mixedComparisons5(signed char a) {
116*67e74705SXin Li   // Case 5: The range is inside and may or may not wrap.
117*67e74705SXin Li   clang_analyzer_eval((a + 5) == 0LL); // expected-warning{{UNKNOWN}}
118*67e74705SXin Li 
119*67e74705SXin Li   if ((a + 5) == 0LL) {
120*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
121*67e74705SXin Li     clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
122*67e74705SXin Li     clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
123*67e74705SXin Li   } else {
124*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
125*67e74705SXin Li     clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
126*67e74705SXin Li     clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
127*67e74705SXin Li   }
128*67e74705SXin Li }
129*67e74705SXin Li 
mixedComparisons6(signed char a)130*67e74705SXin Li void mixedComparisons6(signed char a) {
131*67e74705SXin Li   // Case 6: Only the upper end of the range is outside.
132*67e74705SXin Li   clang_analyzer_eval((a + 5) > 0x81LL); // expected-warning{{UNKNOWN}}
133*67e74705SXin Li 
134*67e74705SXin Li   if ((a + 5) > 0x81LL) {
135*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
136*67e74705SXin Li     clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
137*67e74705SXin Li     clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
138*67e74705SXin Li   }
139*67e74705SXin Li }
140*67e74705SXin Li 
mixedComparisons7(signed char a)141*67e74705SXin Li void mixedComparisons7(signed char a) {
142*67e74705SXin Li   // Case 7: The range wraps around but is entirely outside the symbol's range.
143*67e74705SXin Li   int min = INT_MIN;
144*67e74705SXin Li 
145*67e74705SXin Li   clang_analyzer_eval((a + 2) >= (min + 5LL)); // expected-warning{{TRUE}}
146*67e74705SXin Li 
147*67e74705SXin Li   clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
148*67e74705SXin Li   clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
149*67e74705SXin Li   clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
150*67e74705SXin Li }
151*67e74705SXin Li 
mixedComparisons8(signed char a)152*67e74705SXin Li void mixedComparisons8(signed char a) {
153*67e74705SXin Li   // Case 8: The range wraps, but the upper wrap is out of range.
154*67e74705SXin Li   clang_analyzer_eval((a + 5) < 0LL); // expected-warning{{UNKNOWN}}
155*67e74705SXin Li 
156*67e74705SXin Li   if ((a + 5) < 0LL) {
157*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
158*67e74705SXin Li     clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
159*67e74705SXin Li     clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
160*67e74705SXin Li   }
161*67e74705SXin Li }
162*67e74705SXin Li 
mixedComparisons9(signed char a)163*67e74705SXin Li void mixedComparisons9(signed char a) {
164*67e74705SXin Li   // Case 9: The range is entirely above the symbol's range.
165*67e74705SXin Li   int max = INT_MAX;
166*67e74705SXin Li 
167*67e74705SXin Li   clang_analyzer_eval((a + 2) <= (max - 5LL)); // expected-warning{{TRUE}}
168*67e74705SXin Li 
169*67e74705SXin Li   clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
170*67e74705SXin Li   clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
171*67e74705SXin Li   clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
172*67e74705SXin Li }
173*67e74705SXin Li 
174*67e74705SXin Li 
mixedSignedness1(int a)175*67e74705SXin Li void mixedSignedness1(int a) {
176*67e74705SXin Li   unsigned max = UINT_MAX;
177*67e74705SXin Li   clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
178*67e74705SXin Li   clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
179*67e74705SXin Li   clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
180*67e74705SXin Li }
181*67e74705SXin Li 
mixedSignedness2(int a)182*67e74705SXin Li void mixedSignedness2(int a) {
183*67e74705SXin Li   unsigned max = UINT_MAX;
184*67e74705SXin Li   clang_analyzer_eval(a <= max); // expected-warning{{TRUE}}
185*67e74705SXin Li   clang_analyzer_eval((a + 2) <= max); // expected-warning{{TRUE}}
186*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= max); // expected-warning{{TRUE}}
187*67e74705SXin Li }
188*67e74705SXin Li 
mixedSignedness3(unsigned a)189*67e74705SXin Li void mixedSignedness3(unsigned a) {
190*67e74705SXin Li   int max = INT_MAX;
191*67e74705SXin Li   clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
192*67e74705SXin Li   clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
193*67e74705SXin Li   clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
194*67e74705SXin Li }
195*67e74705SXin Li 
mixedSignedness4(unsigned a)196*67e74705SXin Li void mixedSignedness4(unsigned a) {
197*67e74705SXin Li   int max = INT_MAX;
198*67e74705SXin Li   clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}}
199*67e74705SXin Li   clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}}
200*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}}
201*67e74705SXin Li }
202*67e74705SXin Li 
mixedSignedness5(unsigned a)203*67e74705SXin Li void mixedSignedness5(unsigned a) {
204*67e74705SXin Li   int min = INT_MIN;
205*67e74705SXin Li   clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
206*67e74705SXin Li   clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
207*67e74705SXin Li   clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}}
208*67e74705SXin Li }
209*67e74705SXin Li 
mixedSignedness6(unsigned a)210*67e74705SXin Li void mixedSignedness6(unsigned a) {
211*67e74705SXin Li   int min = INT_MIN;
212*67e74705SXin Li   clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
213*67e74705SXin Li   clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
214*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
215*67e74705SXin Li }
216*67e74705SXin Li 
mixedSignedness7(unsigned a)217*67e74705SXin Li void mixedSignedness7(unsigned a) {
218*67e74705SXin Li   unsigned min = 0;
219*67e74705SXin Li   clang_analyzer_eval(a < min); // expected-warning{{FALSE}}
220*67e74705SXin Li   clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}}
221*67e74705SXin Li   clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
222*67e74705SXin Li }
223*67e74705SXin Li 
mixedSignedness8(unsigned a)224*67e74705SXin Li void mixedSignedness8(unsigned a) {
225*67e74705SXin Li   unsigned min = 0;
226*67e74705SXin Li   clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
227*67e74705SXin Li   clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
228*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
229*67e74705SXin Li }
230*67e74705SXin Li 
mixedSignedness9(unsigned a)231*67e74705SXin Li void mixedSignedness9(unsigned a) {
232*67e74705SXin Li   int min = 0;
233*67e74705SXin Li   clang_analyzer_eval(a < min); // expected-warning{{FALSE}}
234*67e74705SXin Li   clang_analyzer_eval((a + 2) < min); // expected-warning{{FALSE}}
235*67e74705SXin Li   clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
236*67e74705SXin Li }
237*67e74705SXin Li 
mixedSignedness10(unsigned a)238*67e74705SXin Li void mixedSignedness10(unsigned a) {
239*67e74705SXin Li   int min = 0;
240*67e74705SXin Li   clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
241*67e74705SXin Li   clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
242*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
243*67e74705SXin Li }
244*67e74705SXin Li 
mixedSignedness11(int a)245*67e74705SXin Li void mixedSignedness11(int a) {
246*67e74705SXin Li   int min = 0;
247*67e74705SXin Li   clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
248*67e74705SXin Li   clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
249*67e74705SXin Li   clang_analyzer_eval((a + 2U) < min); // expected-warning{{FALSE}}
250*67e74705SXin Li }
251*67e74705SXin Li 
mixedSignedness12(int a)252*67e74705SXin Li void mixedSignedness12(int a) {
253*67e74705SXin Li   int min = 0;
254*67e74705SXin Li   clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
255*67e74705SXin Li   clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
256*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
257*67e74705SXin Li }
258*67e74705SXin Li 
mixedSignedness13(int a)259*67e74705SXin Li void mixedSignedness13(int a) {
260*67e74705SXin Li   unsigned max = INT_MAX;
261*67e74705SXin Li   clang_analyzer_eval(a < max); // expected-warning{{UNKNOWN}}
262*67e74705SXin Li   clang_analyzer_eval((a + 2) < max); // expected-warning{{UNKNOWN}}
263*67e74705SXin Li   clang_analyzer_eval((a + 2U) < max); // expected-warning{{UNKNOWN}}
264*67e74705SXin Li }
265*67e74705SXin Li 
mixedSignedness14(int a)266*67e74705SXin Li void mixedSignedness14(int a) {
267*67e74705SXin Li   unsigned max = INT_MAX;
268*67e74705SXin Li   clang_analyzer_eval(a <= max); // expected-warning{{UNKNOWN}}
269*67e74705SXin Li   clang_analyzer_eval((a + 2) <= max); // expected-warning{{UNKNOWN}}
270*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= max); // expected-warning{{UNKNOWN}}
271*67e74705SXin Li }
272*67e74705SXin Li 
mixedSignedness15(int a)273*67e74705SXin Li void mixedSignedness15(int a) {
274*67e74705SXin Li   unsigned min = INT_MIN;
275*67e74705SXin Li   clang_analyzer_eval(a < min); // expected-warning{{UNKNOWN}}
276*67e74705SXin Li   clang_analyzer_eval((a + 2) < min); // expected-warning{{UNKNOWN}}
277*67e74705SXin Li   clang_analyzer_eval((a + 2U) < min); // expected-warning{{UNKNOWN}}
278*67e74705SXin Li }
279*67e74705SXin Li 
mixedSignedness16(int a)280*67e74705SXin Li void mixedSignedness16(int a) {
281*67e74705SXin Li   unsigned min = INT_MIN;
282*67e74705SXin Li   clang_analyzer_eval(a <= min); // expected-warning{{UNKNOWN}}
283*67e74705SXin Li   clang_analyzer_eval((a + 2) <= min); // expected-warning{{UNKNOWN}}
284*67e74705SXin Li   clang_analyzer_eval((a + 2U) <= min); // expected-warning{{UNKNOWN}}
285*67e74705SXin Li }
286*67e74705SXin Li 
mixedSignedness17(int a)287*67e74705SXin Li void mixedSignedness17(int a) {
288*67e74705SXin Li   unsigned max = INT_MAX;
289*67e74705SXin Li   if (a < max)
290*67e74705SXin Li     return;
291*67e74705SXin Li 
292*67e74705SXin Li   clang_analyzer_eval(a < 0); // expected-warning{{UNKNOWN}}
293*67e74705SXin Li   clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
294*67e74705SXin Li   clang_analyzer_eval(a == INT_MAX); // expected-warning{{UNKNOWN}}
295*67e74705SXin Li }
296*67e74705SXin Li 
mixedSignedness18(int a)297*67e74705SXin Li void mixedSignedness18(int a) {
298*67e74705SXin Li   if (a >= 0)
299*67e74705SXin Li     return;
300*67e74705SXin Li 
301*67e74705SXin Li   clang_analyzer_eval(a < 0); // expected-warning{{TRUE}}
302*67e74705SXin Li   clang_analyzer_eval(a == (unsigned)INT_MIN); // expected-warning{{UNKNOWN}}
303*67e74705SXin Li   clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
304*67e74705SXin Li }
305