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 | |
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 | |
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 | |
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 |
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. |
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 |
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 | |
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 | |
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 | |
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! |
97 | void adjustedGT (unsigned a) { |
98 | clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}} |
99 | } |
100 | |
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 | |
108 | void adjustedLT (unsigned a) { |
109 | clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}} |
110 | } |
111 | |
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. |
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 |
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. |
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 | |
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 | |
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 | |
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. |
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 | |
187 | void mixedSignedness2(int a) { |
188 | if (a != -1) |
189 | return; |
190 | clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}} |
191 | } |
192 | |
193 | void mixedSignedness3(unsigned a) { |
194 | if (a != UINT_MAX) |
195 | return; |
196 | clang_analyzer_eval(a == -1); // expected-warning{{TRUE}} |
197 | } |
198 | |
199 | |
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 | |
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 | |