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