[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / std-c-library-functions-arg-constraints.c
blob1e9165321232deaf1532bb31b2cb8fdec9b36f82
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 \
9 // RUN: -verify=report
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();
25 int glob;
27 #define EOF -1
29 int isalnum(int);
31 void test_alnum_concrete(int v) {
32 int ret = isalnum(256); // \
33 // report-warning{{Function argument constraint is not satisfied}} \
34 // report-note{{}} \
35 // bugpath-warning{{Function argument constraint is not satisfied}} \
36 // bugpath-note{{}} \
37 // bugpath-note{{Function argument constraint is not satisfied}}
38 (void)ret;
41 void test_alnum_symbolic(int x) {
42 int ret = isalnum(x); // \
43 // bugpath-note{{Assuming the character is non-alphanumeric}}
44 (void)ret;
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) {
55 if (x > 255) { // \
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}} \
61 // report-note{{}} \
62 // bugpath-warning{{Function argument constraint is not satisfied}} \
63 // bugpath-note{{}} \
64 // bugpath-note{{Function argument constraint is not satisfied}}
66 (void)ret;
70 int toupper(int);
72 void test_toupper_concrete(int v) {
73 int ret = toupper(256); // \
74 // report-warning{{Function argument constraint is not satisfied}} \
75 // report-note{{}} \
76 // bugpath-warning{{Function argument constraint is not satisfied}} \
77 // bugpath-note{{}} \
78 // bugpath-note{{Function argument constraint is not satisfied}}
79 (void)ret;
82 void test_toupper_symbolic(int x) {
83 int ret = toupper(x);
84 (void)ret;
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) {
95 if (x > 255) { // \
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}} \
101 // report-note{{}} \
102 // bugpath-warning{{Function argument constraint is not satisfied}} \
103 // bugpath-note{{}} \
104 // bugpath-note{{Function argument constraint is not satisfied}}
106 (void)ret;
110 int tolower(int);
112 void test_tolower_concrete(int v) {
113 int ret = tolower(256); // \
114 // report-warning{{Function argument constraint is not satisfied}} \
115 // report-note{{}} \
116 // bugpath-warning{{Function argument constraint is not satisfied}} \
117 // bugpath-note{{}} \
118 // bugpath-note{{Function argument constraint is not satisfied}}
119 (void)ret;
122 void test_tolower_symbolic(int x) {
123 int ret = tolower(x);
124 (void)ret;
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) {
135 if (x > 255) { // \
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}} \
141 // report-note{{}} \
142 // bugpath-warning{{Function argument constraint is not satisfied}} \
143 // bugpath-note{{}} \
144 // bugpath-note{{Function argument constraint is not satisfied}}
146 (void)ret;
150 int toascii(int);
152 void test_toascii_concrete(int v) {
153 int ret = toascii(256); // \
154 // report-warning{{Function argument constraint is not satisfied}} \
155 // report-note{{}} \
156 // bugpath-warning{{Function argument constraint is not satisfied}} \
157 // bugpath-note{{}} \
158 // bugpath-note{{Function argument constraint is not satisfied}}
159 (void)ret;
162 void test_toascii_symbolic(int x) {
163 int ret = toascii(x);
164 (void)ret;
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) {
175 if (x > 255) { // \
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}} \
181 // report-note{{}} \
182 // bugpath-warning{{Function argument constraint is not satisfied}} \
183 // bugpath-note{{}} \
184 // bugpath-note{{Function argument constraint is not satisfied}}
186 (void)ret;
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}} \
196 // report-note{{}} \
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}} \
214 // report-note{{}} \
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) {
220 if (fp) // \
221 // bugpath-note{{Assuming 'fp' is null}} \
222 // bugpath-note{{Taking false branch}}
223 return;
224 size_t ret = fread(buf, size, n, fp); // \
225 // report-warning{{Function argument constraint is not satisfied}} \
226 // report-note{{}} \
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}} \
246 // report-note{{}} \
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
255 // FALSE.
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}} \
283 // report-note{{}} \
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}} \
294 // report-note{{}} \
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) {
300 char buf[3];
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) {
309 char buf[3];
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}} \
323 // report-note{{}} \
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) {
329 short buf[3];
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) {
337 short buf[3];
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}} \
351 // report-note{{}} \
352 // bugpath-warning{{Function argument constraint is not satisfied}} \
353 // bugpath-note{{}} \
354 // bugpath-note{{Function argument constraint is not satisfied}}