1 // Check the basic reporting/warning and the application of constraints.
2 // RUN: %clang_analyze_cc1 %s \
3 // RUN: -analyzer-checker=core \
4 // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
5 // RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
6 // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
7 // RUN: -analyzer-checker=debug.ExprInspection \
8 // RUN: -triple x86_64-unknown-linux-gnu \
11 // Check the bugpath related to the reports.
12 // RUN: %clang_analyze_cc1 %s \
13 // RUN: -analyzer-checker=core \
14 // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
15 // RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
16 // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
17 // RUN: -analyzer-checker=debug.ExprInspection \
18 // RUN: -triple x86_64-unknown-linux-gnu \
19 // RUN: -analyzer-output=text \
20 // RUN: -verify=bugpath
22 void clang_analyzer_eval(int);
23 void clang_analyzer_warnIfReached();
31 void test_alnum_concrete(int v
) {
32 int ret
= isalnum(256); // \
33 // report-warning{{Function argument constraint is not satisfied}} \
35 // bugpath-warning{{Function argument constraint is not satisfied}} \
37 // bugpath-note{{Function argument constraint is not satisfied}}
41 void test_alnum_symbolic(int x
) {
42 int ret
= isalnum(x
); // \
43 // bugpath-note{{Assuming the character is non-alphanumeric}}
46 clang_analyzer_eval(EOF
<= x
&& x
<= 255); // \
47 // report-warning{{TRUE}} \
48 // bugpath-warning{{TRUE}} \
49 // bugpath-note{{TRUE}} \
50 // bugpath-note{{Left side of '&&' is true}} \
51 // bugpath-note{{'x' is <= 255}}
54 void test_alnum_symbolic2(int x
) {
56 // bugpath-note{{Assuming 'x' is > 255}} \
57 // bugpath-note{{Taking true branch}}
59 int ret
= isalnum(x
); // \
60 // report-warning{{Function argument constraint is not satisfied}} \
62 // bugpath-warning{{Function argument constraint is not satisfied}} \
64 // bugpath-note{{Function argument constraint is not satisfied}}
72 void test_toupper_concrete(int v
) {
73 int ret
= toupper(256); // \
74 // report-warning{{Function argument constraint is not satisfied}} \
76 // bugpath-warning{{Function argument constraint is not satisfied}} \
78 // bugpath-note{{Function argument constraint is not satisfied}}
82 void test_toupper_symbolic(int x
) {
86 clang_analyzer_eval(EOF
<= x
&& x
<= 255); // \
87 // report-warning{{TRUE}} \
88 // bugpath-warning{{TRUE}} \
89 // bugpath-note{{TRUE}} \
90 // bugpath-note{{Left side of '&&' is true}} \
91 // bugpath-note{{'x' is <= 255}}
94 void test_toupper_symbolic2(int x
) {
96 // bugpath-note{{Assuming 'x' is > 255}} \
97 // bugpath-note{{Taking true branch}}
99 int ret
= toupper(x
); // \
100 // report-warning{{Function argument constraint is not satisfied}} \
102 // bugpath-warning{{Function argument constraint is not satisfied}} \
103 // bugpath-note{{}} \
104 // bugpath-note{{Function argument constraint is not satisfied}}
112 void test_tolower_concrete(int v
) {
113 int ret
= tolower(256); // \
114 // report-warning{{Function argument constraint is not satisfied}} \
116 // bugpath-warning{{Function argument constraint is not satisfied}} \
117 // bugpath-note{{}} \
118 // bugpath-note{{Function argument constraint is not satisfied}}
122 void test_tolower_symbolic(int x
) {
123 int ret
= tolower(x
);
126 clang_analyzer_eval(EOF
<= x
&& x
<= 255); // \
127 // report-warning{{TRUE}} \
128 // bugpath-warning{{TRUE}} \
129 // bugpath-note{{TRUE}} \
130 // bugpath-note{{Left side of '&&' is true}} \
131 // bugpath-note{{'x' is <= 255}}
134 void test_tolower_symbolic2(int x
) {
136 // bugpath-note{{Assuming 'x' is > 255}} \
137 // bugpath-note{{Taking true branch}}
139 int ret
= tolower(x
); // \
140 // report-warning{{Function argument constraint is not satisfied}} \
142 // bugpath-warning{{Function argument constraint is not satisfied}} \
143 // bugpath-note{{}} \
144 // bugpath-note{{Function argument constraint is not satisfied}}
152 void test_toascii_concrete(int v
) {
153 int ret
= toascii(256); // \
154 // report-warning{{Function argument constraint is not satisfied}} \
156 // bugpath-warning{{Function argument constraint is not satisfied}} \
157 // bugpath-note{{}} \
158 // bugpath-note{{Function argument constraint is not satisfied}}
162 void test_toascii_symbolic(int x
) {
163 int ret
= toascii(x
);
166 clang_analyzer_eval(EOF
<= x
&& x
<= 255); // \
167 // report-warning{{TRUE}} \
168 // bugpath-warning{{TRUE}} \
169 // bugpath-note{{TRUE}} \
170 // bugpath-note{{Left side of '&&' is true}} \
171 // bugpath-note{{'x' is <= 255}}
174 void test_toascii_symbolic2(int x
) {
176 // bugpath-note{{Assuming 'x' is > 255}} \
177 // bugpath-note{{Taking true branch}}
179 int ret
= toascii(x
); // \
180 // report-warning{{Function argument constraint is not satisfied}} \
182 // bugpath-warning{{Function argument constraint is not satisfied}} \
183 // bugpath-note{{}} \
184 // bugpath-note{{Function argument constraint is not satisfied}}
190 typedef struct FILE FILE;
191 typedef typeof(sizeof(int)) size_t;
192 size_t fread(void *restrict
, size_t, size_t, FILE *restrict
);
193 void test_notnull_concrete(FILE *fp
) {
194 fread(0, sizeof(int), 10, fp
); // \
195 // report-warning{{Function argument constraint is not satisfied}} \
197 // bugpath-warning{{Function argument constraint is not satisfied}} \
198 // bugpath-note{{}} \
199 // bugpath-note{{Function argument constraint is not satisfied}}
201 void test_notnull_symbolic(FILE *fp
, int *buf
) {
202 fread(buf
, sizeof(int), 10, fp
);
203 clang_analyzer_eval(buf
!= 0); // \
204 // report-warning{{TRUE}} \
205 // bugpath-warning{{TRUE}} \
206 // bugpath-note{{TRUE}} \
207 // bugpath-note{{'buf' is not equal to null}}
209 void test_notnull_symbolic2(FILE *fp
, int *buf
) {
210 if (!buf
) // bugpath-note{{Assuming 'buf' is null}} \
211 // bugpath-note{{Taking true branch}}
212 fread(buf
, sizeof(int), 10, fp
); // \
213 // report-warning{{Function argument constraint is not satisfied}} \
215 // bugpath-warning{{Function argument constraint is not satisfied}} \
216 // bugpath-note{{}} \
217 // bugpath-note{{Function argument constraint is not satisfied}}
219 void test_no_node_after_bug(FILE *fp
, size_t size
, size_t n
, void *buf
) {
221 // bugpath-note{{Assuming 'fp' is null}} \
222 // bugpath-note{{Taking false branch}}
224 size_t ret
= fread(buf
, size
, n
, fp
); // \
225 // report-warning{{Function argument constraint is not satisfied}} \
227 // bugpath-warning{{Function argument constraint is not satisfied}} \
228 // bugpath-note{{}} \
229 // bugpath-note{{Function argument constraint is not satisfied}}
230 clang_analyzer_warnIfReached(); // not reachable
233 typedef __WCHAR_TYPE__
wchar_t;
234 // This is one test case for the ARR38-C SEI-CERT rule.
235 void ARR38_C_F(FILE *file
) {
236 enum { BUFFER_SIZE
= 1024 };
237 wchar_t wbuf
[BUFFER_SIZE
]; // bugpath-note{{'wbuf' initialized here}}
239 const size_t size
= sizeof(*wbuf
); // bugpath-note{{'size' initialized to}}
240 const size_t nitems
= sizeof(wbuf
); // bugpath-note{{'nitems' initialized to}}
242 // The 3rd parameter should be the number of elements to read, not
243 // the size in bytes.
244 fread(wbuf
, size
, nitems
, file
); // \
245 // report-warning{{Function argument constraint is not satisfied}} \
247 // bugpath-warning{{Function argument constraint is not satisfied}} \
248 // bugpath-note{{}} \
249 // bugpath-note{{Function argument constraint is not satisfied}}
252 int __two_constrained_args(int, int);
253 void test_constraints_on_multiple_args(int x
, int y
) {
254 // State split should not happen here. I.e. x == 1 should not be evaluated
256 __two_constrained_args(x
, y
);
257 //NOTE! Because of the second `clang_analyzer_eval` call we have two bug
258 clang_analyzer_eval(x
== 1); // \
259 // report-warning{{TRUE}} \
260 // bugpath-warning{{TRUE}} \
261 // bugpath-note{{TRUE}}
262 clang_analyzer_eval(y
== 1); // \
263 // report-warning{{TRUE}} \
264 // bugpath-warning{{TRUE}} \
265 // bugpath-note{{TRUE}}
268 int __arg_constrained_twice(int);
269 void test_multiple_constraints_on_same_arg(int x
) {
270 __arg_constrained_twice(x
);
271 clang_analyzer_eval(x
< 1 || x
> 2); // \
272 // report-warning{{TRUE}} \
273 // bugpath-warning{{TRUE}} \
274 // bugpath-note{{TRUE}} \
275 // bugpath-note{{Assuming 'x' is < 1}} \
276 // bugpath-note{{Left side of '||' is true}}
279 int __variadic(void *stream
, const char *format
, ...);
280 void test_arg_constraint_on_variadic_fun(void) {
281 __variadic(0, "%d%d", 1, 2); // \
282 // report-warning{{Function argument constraint is not satisfied}} \
284 // bugpath-warning{{Function argument constraint is not satisfied}} \
285 // bugpath-note{{}} \
286 // bugpath-note{{Function argument constraint is not satisfied}}
289 int __buf_size_arg_constraint(const void *, size_t);
290 void test_buf_size_concrete(void) {
291 char buf
[3]; // bugpath-note{{'buf' initialized here}}
292 __buf_size_arg_constraint(buf
, 4); // \
293 // report-warning{{Function argument constraint is not satisfied}} \
295 // bugpath-warning{{Function argument constraint is not satisfied}} \
296 // bugpath-note{{}} \
297 // bugpath-note{{Function argument constraint is not satisfied}}
299 void test_buf_size_symbolic(int s
) {
301 __buf_size_arg_constraint(buf
, s
);
302 clang_analyzer_eval(s
<= 3); // \
303 // report-warning{{TRUE}} \
304 // bugpath-warning{{TRUE}} \
305 // bugpath-note{{TRUE}} \
306 // bugpath-note{{'s' is <= 3}}
308 void test_buf_size_symbolic_and_offset(int s
) {
310 __buf_size_arg_constraint(buf
+ 1, s
);
311 clang_analyzer_eval(s
<= 2); // \
312 // report-warning{{TRUE}} \
313 // bugpath-warning{{TRUE}} \
314 // bugpath-note{{TRUE}} \
315 // bugpath-note{{'s' is <= 2}}
318 int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
319 void test_buf_size_concrete_with_multiplication(void) {
320 short buf
[3]; // bugpath-note{{'buf' initialized here}}
321 __buf_size_arg_constraint_mul(buf
, 4, sizeof(short)); // \
322 // report-warning{{Function argument constraint is not satisfied}} \
324 // bugpath-warning{{Function argument constraint is not satisfied}} \
325 // bugpath-note{{}} \
326 // bugpath-note{{Function argument constraint is not satisfied}}
328 void test_buf_size_symbolic_with_multiplication(size_t s
) {
330 __buf_size_arg_constraint_mul(buf
, s
, sizeof(short));
331 clang_analyzer_eval(s
* sizeof(short) <= 6); // \
332 // report-warning{{TRUE}} \
333 // bugpath-warning{{TRUE}} \
334 // bugpath-note{{TRUE}}
336 void test_buf_size_symbolic_and_offset_with_multiplication(size_t s
) {
338 __buf_size_arg_constraint_mul(buf
+ 1, s
, sizeof(short));
339 clang_analyzer_eval(s
* sizeof(short) <= 4); // \
340 // report-warning{{TRUE}} \
341 // bugpath-warning{{TRUE}} \
342 // bugpath-note{{TRUE}}
345 // The minimum buffer size for this function is set to 10.
346 int __buf_size_arg_constraint_concrete(const void *);
347 void test_min_buf_size(void) {
348 char buf
[9];// bugpath-note{{'buf' initialized here}}
349 __buf_size_arg_constraint_concrete(buf
); // \
350 // report-warning{{Function argument constraint is not satisfied}} \
352 // bugpath-warning{{Function argument constraint is not satisfied}} \
353 // bugpath-note{{}} \
354 // bugpath-note{{Function argument constraint is not satisfied}}