blob: a64c9102fcc2f9d983a0b2c272c79119b64e6ab3 [file] [log] [blame]
Jordy Rose9e607dd2012-05-03 07:33:56 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=range %s
Jordy Roseba0f61c2010-06-18 22:49:11 +00002
3// These are used to trigger warnings.
4typedef typeof(sizeof(int)) size_t;
5void *malloc(size_t);
6void free(void *);
7#define NULL ((void*)0)
Jordy Rose9e607dd2012-05-03 07:33:56 +00008#define UINT_MAX (~0U)
Jordy Rose1d8db492012-05-08 03:27:16 +00009#define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
10#define INT_MIN (-INT_MAX - 1)
11
Jordy Roseba0f61c2010-06-18 22:49:11 +000012
13// Each of these adjusted ranges has an adjustment small enough to split the
14// solution range across an overflow boundary (Min for <, Max for >).
15// This corresponds to one set of branches in RangeConstraintManager.
16void smallAdjustmentGT (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000017 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000018 if (a+2 > 1)
19 b = malloc(1);
20 if (a == UINT_MAX-1 || a == UINT_MAX)
21 return; // no-warning
22 else if (a < UINT_MAX-1)
23 free(b);
24 return; // no-warning
25}
26
27void smallAdjustmentGE (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000028 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000029 if (a+2 >= 1)
30 b = malloc(1);
31 if (a == UINT_MAX-1)
32 return; // no-warning
33 else if (a < UINT_MAX-1 || a == UINT_MAX)
34 free(b);
35 return; // no-warning
36}
37
38void smallAdjustmentLT (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000039 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000040 if (a+1 < 2)
41 b = malloc(1);
42 if (a == 0 || a == UINT_MAX)
43 free(b);
44 return; // no-warning
45}
46
47void smallAdjustmentLE (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000048 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000049 if (a+1 <= 2)
50 b = malloc(1);
51 if (a == 0 || a == 1 || a == UINT_MAX)
52 free(b);
53 return; // no-warning
54}
55
56
57// Each of these adjusted ranges has an adjustment large enough to push the
58// comparison value over an overflow boundary (Min for <, Max for >).
59// This corresponds to one set of branches in RangeConstraintManager.
60void largeAdjustmentGT (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000061 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000062 if (a-2 > UINT_MAX-1)
63 b = malloc(1);
64 if (a == 1 || a == 0)
65 free(b);
66 else if (a > 1)
67 free(b);
68 return; // no-warning
69}
70
71void largeAdjustmentGE (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000072 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000073 if (a-2 >= UINT_MAX-1)
74 b = malloc(1);
75 if (a > 1)
76 return; // no-warning
77 else if (a == 1 || a == 0)
78 free(b);
79 return; // no-warning
80}
81
82void largeAdjustmentLT (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000083 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000084 if (a+2 < 1)
85 b = malloc(1);
86 if (a == UINT_MAX-1 || a == UINT_MAX)
87 free(b);
88 else if (a < UINT_MAX-1)
89 return; // no-warning
90 return; // no-warning
91}
92
93void largeAdjustmentLE (unsigned a) {
Jordy Rose9e607dd2012-05-03 07:33:56 +000094 void *b = NULL;
Jordy Roseba0f61c2010-06-18 22:49:11 +000095 if (a+2 <= 1)
96 b = malloc(1);
97 if (a < UINT_MAX-1)
98 return; // no-warning
99 else if (a == UINT_MAX-1 || a == UINT_MAX)
100 free(b);
101 return; // no-warning
102}
Jordy Rose1d8db492012-05-08 03:27:16 +0000103
104
105// Test the nine cases in RangeConstraintManager's pinning logic.
106void mixedComparisons1(signed char a) {
107 // Case 1: The range is entirely below the symbol's range.
108 int min = INT_MIN;
109
110 if ((a - 2) < (min + 5LL))
111 return; // expected-warning{{never executed}}
112
113 if (a == 0)
114 return; // no-warning
115 if (a == 0x7F)
116 return; // no-warning
117 if (a == -0x80)
118 return; // no-warning
119 return; // no-warning
120}
121
122void mixedComparisons2(signed char a) {
123 // Case 2: Only the lower end of the range is outside.
124 if ((a - 5) < (-0x81LL)) {
125 if (a == 0)
126 return; // expected-warning{{never executed}}
127 if (a == 0x7F)
128 return; // expected-warning{{never executed}}
129 if (a == -0x80)
130 return; // no-warning
131 return; // no-warning
132 } else {
133 return; // no-warning
134 }
135}
136
137void mixedComparisons3(signed char a) {
138 // Case 3: The entire symbol range is covered.
139 if ((a - 0x200) < -0x100LL) {
140 if (a == 0)
141 return; // no-warning
142 if (a == 0x7F)
143 return; // no-warning
144 if (a == -0x80)
145 return; // no-warning
146 return; // no-warning
147 } else {
148 return; // expected-warning{{never executed}}
149 }
150}
151
152void mixedComparisons4(signed char a) {
153 // Case 4: The range wraps around, but the lower wrap is out-of-range.
154 if ((a - 5) > 0LL) {
155 if (a == 0)
156 return; // expected-warning{{never executed}}
157 if (a == 0x7F)
158 return; // no-warning
159 if (a == -0x80)
160 return; // expected-warning{{never executed}}
161 return; // no-warning
162 } else {
163 return; // no-warning
164 }
165}
166
167void mixedComparisons5(signed char a) {
168 // Case 5a: The range is inside and does not wrap.
169 if ((a + 5) == 0LL) {
170 if (a == 0)
171 return; // expected-warning{{never executed}}
172 if (a == 0x7F)
173 return; // expected-warning{{never executed}}
174 if (a == -0x80)
175 return; // expected-warning{{never executed}}
176 return; // no-warning
177 } else {
178 return; // no-warning
179 }
180}
181
182void mixedComparisons5Wrap(signed char a) {
183 // Case 5b: The range is inside and does wrap.
184 if ((a + 5) != 0LL) {
185 if (a == 0)
186 return; // no-warning
187 if (a == 0x7F)
188 return; // no-warning
189 if (a == -0x80)
190 return; // no-warning
191 return; // no-warning
192 } else {
193 return; // no-warning
194 }
195}
196
197void mixedComparisons6(signed char a) {
198 // Case 6: Only the upper end of the range is outside.
199 if ((a + 5) > 0x81LL) {
200 if (a == 0)
201 return; // expected-warning{{never executed}}
202 if (a == 0x7F)
203 return; // no-warning
204 if (a == -0x80)
205 return; // expected-warning{{never executed}}
206 return; // no-warning
207 } else {
208 return; // no-warning
209 }
210}
211
212void mixedComparisons7(signed char a) {
213 // Case 7: The range wraps around but is entirely outside the symbol's range.
214 int min = INT_MIN;
215
216 if ((a + 2) < (min + 5LL))
217 return; // expected-warning{{never executed}}
218
219 if (a == 0)
220 return; // no-warning
221 if (a == 0x7F)
222 return; // no-warning
223 if (a == -0x80)
224 return; // no-warning
225 return; // no-warning
226}
227
228void mixedComparisons8(signed char a) {
229 // Case 8: The range wraps, but the upper wrap is out of range.
230 if ((a + 5) < 0LL) {
231 if (a == 0)
232 return; // expected-warning{{never executed}}
233 if (a == 0x7F)
234 return; // expected-warning{{never executed}}
235 if (a == -0x80)
236 return; // no-warning
237 return; // no-warning
238 } else {
239 return; // no-warning
240 }
241}
242
243void mixedComparisons9(signed char a) {
244 // Case 9: The range is entirely above the symbol's range.
245 int max = INT_MAX;
246
247 if ((a + 2) > (max - 5LL))
248 return; // expected-warning{{never executed}}
249
250 if (a == 0)
251 return; // no-warning
252 if (a == 0x7F)
253 return; // no-warning
254 if (a == -0x80)
255 return; // no-warning
256 return; // no-warning
257}