xref: /aosp_15_r20/external/clang/test/Analysis/additive-folding.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range -Wno-tautological-compare %s
2*67e74705SXin Li 
3*67e74705SXin Li void clang_analyzer_eval(bool);
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 //  Plus/minus
11*67e74705SXin Li //---------------
12*67e74705SXin Li 
separateExpressions(int a)13*67e74705SXin Li void separateExpressions (int a) {
14*67e74705SXin Li   int b = a + 1;
15*67e74705SXin Li   --b;
16*67e74705SXin Li 
17*67e74705SXin Li   clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
18*67e74705SXin Li }
19*67e74705SXin Li 
oneLongExpression(int a)20*67e74705SXin Li void oneLongExpression (int a) {
21*67e74705SXin Li   // Expression canonicalization should still allow this to work, even though
22*67e74705SXin Li   // the first term is on the left.
23*67e74705SXin Li   int b = 15 + a + 15 - 10 - 20;
24*67e74705SXin Li 
25*67e74705SXin Li   clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
26*67e74705SXin Li }
27*67e74705SXin Li 
mixedTypes(int a)28*67e74705SXin Li void mixedTypes (int a) {
29*67e74705SXin Li   // Different additive types should not cause crashes when constant-folding.
30*67e74705SXin Li   // This is part of PR7406.
31*67e74705SXin Li   int b = a + 1LL;
32*67e74705SXin Li   clang_analyzer_eval(a != 0 && (b-1) == 0); // not crash, expected-warning{{FALSE}}
33*67e74705SXin Li 
34*67e74705SXin Li   int c = a + 1U;
35*67e74705SXin Li   clang_analyzer_eval(a != 0 && (c-1) == 0); // not crash, expected-warning{{FALSE}}
36*67e74705SXin Li }
37*67e74705SXin Li 
38*67e74705SXin Li //---------------
39*67e74705SXin Li //  Comparisons
40*67e74705SXin Li //---------------
41*67e74705SXin Li 
42*67e74705SXin Li // Equality and inequality only
eq_ne(unsigned a)43*67e74705SXin Li void eq_ne (unsigned a) {
44*67e74705SXin Li   if (a == UINT_MAX) {
45*67e74705SXin Li     clang_analyzer_eval(a+1 == 0); // expected-warning{{TRUE}}
46*67e74705SXin Li     clang_analyzer_eval(a-1 == UINT_MAX-1); // expected-warning{{TRUE}}
47*67e74705SXin Li   } else {
48*67e74705SXin Li     clang_analyzer_eval(a+1 != 0); // expected-warning{{TRUE}}
49*67e74705SXin Li     clang_analyzer_eval(a-1 != UINT_MAX-1); // expected-warning{{TRUE}}
50*67e74705SXin Li   }
51*67e74705SXin Li }
52*67e74705SXin Li 
53*67e74705SXin Li // Mixed typed inequalities (part of PR7406)
54*67e74705SXin Li // These should not crash.
mixed_eq_ne(int a)55*67e74705SXin Li void mixed_eq_ne (int a) {
56*67e74705SXin Li   if (a == 1) {
57*67e74705SXin Li     clang_analyzer_eval(a+1U == 2); // expected-warning{{TRUE}}
58*67e74705SXin Li     clang_analyzer_eval(a-1U == 0); // expected-warning{{TRUE}}
59*67e74705SXin Li   } else {
60*67e74705SXin Li     clang_analyzer_eval(a+1U != 2); // expected-warning{{TRUE}}
61*67e74705SXin Li     clang_analyzer_eval(a-1U != 0); // expected-warning{{TRUE}}
62*67e74705SXin Li   }
63*67e74705SXin Li }
64*67e74705SXin Li 
65*67e74705SXin Li 
66*67e74705SXin Li // Simple order comparisons with no adjustment
baselineGT(unsigned a)67*67e74705SXin Li void baselineGT (unsigned a) {
68*67e74705SXin Li   if (a > 0)
69*67e74705SXin Li     clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
70*67e74705SXin Li   else
71*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
72*67e74705SXin Li }
73*67e74705SXin Li 
baselineGE(unsigned a)74*67e74705SXin Li void baselineGE (unsigned a) {
75*67e74705SXin Li   if (a >= UINT_MAX)
76*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
77*67e74705SXin Li   else
78*67e74705SXin Li     clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
79*67e74705SXin Li }
80*67e74705SXin Li 
baselineLT(unsigned a)81*67e74705SXin Li void baselineLT (unsigned a) {
82*67e74705SXin Li   if (a < UINT_MAX)
83*67e74705SXin Li     clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
84*67e74705SXin Li   else
85*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
86*67e74705SXin Li }
87*67e74705SXin Li 
baselineLE(unsigned a)88*67e74705SXin Li void baselineLE (unsigned a) {
89*67e74705SXin Li   if (a <= 0)
90*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
91*67e74705SXin Li   else
92*67e74705SXin Li     clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
93*67e74705SXin Li }
94*67e74705SXin Li 
95*67e74705SXin Li 
96*67e74705SXin Li // Adjustment gives each of these an extra solution!
adjustedGT(unsigned a)97*67e74705SXin Li void adjustedGT (unsigned a) {
98*67e74705SXin Li   clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
99*67e74705SXin Li }
100*67e74705SXin Li 
adjustedGE(unsigned a)101*67e74705SXin Li void adjustedGE (unsigned a) {
102*67e74705SXin Li   clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
103*67e74705SXin Li 
104*67e74705SXin Li   if (a-1 >= UINT_MAX-1)
105*67e74705SXin Li     clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
106*67e74705SXin Li }
107*67e74705SXin Li 
adjustedLT(unsigned a)108*67e74705SXin Li void adjustedLT (unsigned a) {
109*67e74705SXin Li   clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}}
110*67e74705SXin Li }
111*67e74705SXin Li 
adjustedLE(unsigned a)112*67e74705SXin Li void adjustedLE (unsigned a) {
113*67e74705SXin Li   clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}}
114*67e74705SXin Li 
115*67e74705SXin Li   if (a+1 <= 1)
116*67e74705SXin Li     clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
117*67e74705SXin Li }
118*67e74705SXin Li 
119*67e74705SXin Li 
120*67e74705SXin Li // Tautologies
121*67e74705SXin Li // The negative forms are exercised as well
122*67e74705SXin Li // because clang_analyzer_eval tests both possibilities.
tautologies(unsigned a)123*67e74705SXin Li void tautologies(unsigned a) {
124*67e74705SXin Li   clang_analyzer_eval(a <= UINT_MAX); // expected-warning{{TRUE}}
125*67e74705SXin Li   clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
126*67e74705SXin Li }
127*67e74705SXin Li 
128*67e74705SXin Li 
129*67e74705SXin Li // Tautologies from outside the range of the symbol
tautologiesOutside(unsigned char a)130*67e74705SXin Li void tautologiesOutside(unsigned char a) {
131*67e74705SXin Li   clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}}
132*67e74705SXin Li   clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}}
133*67e74705SXin Li 
134*67e74705SXin Li   clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}}
135*67e74705SXin Li   clang_analyzer_eval(a != -1); // expected-warning{{TRUE}}
136*67e74705SXin Li 
137*67e74705SXin Li   clang_analyzer_eval(a > -1); // expected-warning{{TRUE}}
138*67e74705SXin Li   clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}}
139*67e74705SXin Li }
140*67e74705SXin Li 
141*67e74705SXin Li 
142*67e74705SXin Li // Wraparound with mixed types. Note that the analyzer assumes
143*67e74705SXin Li // -fwrapv semantics.
mixedWraparoundSanityCheck(int a)144*67e74705SXin Li void mixedWraparoundSanityCheck(int a) {
145*67e74705SXin Li   int max = INT_MAX;
146*67e74705SXin Li   int min = INT_MIN;
147*67e74705SXin Li 
148*67e74705SXin Li   int b = a + 1;
149*67e74705SXin Li   clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}}
150*67e74705SXin Li }
151*67e74705SXin Li 
mixedWraparoundLE_GT(int a)152*67e74705SXin Li void mixedWraparoundLE_GT(int a) {
153*67e74705SXin Li   int max = INT_MAX;
154*67e74705SXin Li   int min = INT_MIN;
155*67e74705SXin Li 
156*67e74705SXin Li   clang_analyzer_eval((a + 2) <= (max + 1LL)); // expected-warning{{TRUE}}
157*67e74705SXin Li   clang_analyzer_eval((a - 2) > (min - 1LL)); // expected-warning{{TRUE}}
158*67e74705SXin Li   clang_analyzer_eval((a + 2LL) <= max); // expected-warning{{UNKNOWN}}
159*67e74705SXin Li }
160*67e74705SXin Li 
mixedWraparoundGE_LT(int a)161*67e74705SXin Li void mixedWraparoundGE_LT(int a) {
162*67e74705SXin Li   int max = INT_MAX;
163*67e74705SXin Li   int min = INT_MIN;
164*67e74705SXin Li 
165*67e74705SXin Li   clang_analyzer_eval((a + 2) < (max + 1LL)); // expected-warning{{TRUE}}
166*67e74705SXin Li   clang_analyzer_eval((a - 2) >= (min - 1LL)); // expected-warning{{TRUE}}
167*67e74705SXin Li   clang_analyzer_eval((a - 2LL) >= min); // expected-warning{{UNKNOWN}}
168*67e74705SXin Li }
169*67e74705SXin Li 
mixedWraparoundEQ_NE(int a)170*67e74705SXin Li void mixedWraparoundEQ_NE(int a) {
171*67e74705SXin Li   int max = INT_MAX;
172*67e74705SXin Li 
173*67e74705SXin Li   clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}}
174*67e74705SXin Li   clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}}
175*67e74705SXin Li }
176*67e74705SXin Li 
177*67e74705SXin Li 
178*67e74705SXin Li // Mixed-signedness comparisons.
mixedSignedness(int a,unsigned b)179*67e74705SXin Li void mixedSignedness(int a, unsigned b) {
180*67e74705SXin Li   int sMin = INT_MIN;
181*67e74705SXin Li   unsigned uMin = INT_MIN;
182*67e74705SXin Li 
183*67e74705SXin Li   clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}}
184*67e74705SXin Li   clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}}
185*67e74705SXin Li }
186*67e74705SXin Li 
mixedSignedness2(int a)187*67e74705SXin Li void mixedSignedness2(int a) {
188*67e74705SXin Li   if (a != -1)
189*67e74705SXin Li     return;
190*67e74705SXin Li   clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
191*67e74705SXin Li }
192*67e74705SXin Li 
mixedSignedness3(unsigned a)193*67e74705SXin Li void mixedSignedness3(unsigned a) {
194*67e74705SXin Li   if (a != UINT_MAX)
195*67e74705SXin Li     return;
196*67e74705SXin Li   clang_analyzer_eval(a == -1); // expected-warning{{TRUE}}
197*67e74705SXin Li }
198*67e74705SXin Li 
199*67e74705SXin Li 
multiplicativeSanityTest(int x)200*67e74705SXin Li void multiplicativeSanityTest(int x) {
201*67e74705SXin Li   // At one point we were ignoring the *4 completely -- the constraint manager
202*67e74705SXin Li   // would see x < 8 and then declare the assertion to be known false.
203*67e74705SXin Li   if (x*4 < 8)
204*67e74705SXin Li     return;
205*67e74705SXin Li 
206*67e74705SXin Li   clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
207*67e74705SXin Li }
208