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