blob: afc2ce28efc622941cd1943a91566308345499cb [file] [log] [blame]
Gabor Marton94061df2020-03-20 16:20:53 +01001// 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 \
Kirstóf Umanncfd6b4b2020-05-27 12:27:32 +02005// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
Gabor Marton15252322020-04-02 16:59:02 +02006// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
Gabor Marton94061df2020-03-20 16:20:53 +01007// RUN: -analyzer-checker=debug.ExprInspection \
8// RUN: -triple x86_64-unknown-linux-gnu \
9// RUN: -verify=report
10
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 \
Kirstóf Umanncfd6b4b2020-05-27 12:27:32 +020015// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
Gabor Marton15252322020-04-02 16:59:02 +020016// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
Gabor Marton94061df2020-03-20 16:20:53 +010017// RUN: -analyzer-checker=debug.ExprInspection \
18// RUN: -triple x86_64-unknown-linux-gnu \
19// RUN: -analyzer-output=text \
20// RUN: -verify=bugpath
21
22void clang_analyzer_eval(int);
23
24int glob;
25
26#define EOF -1
27
28int isalnum(int);
29
30void test_alnum_concrete(int v) {
31 int ret = isalnum(256); // \
32 // report-warning{{Function argument constraint is not satisfied}} \
33 // bugpath-warning{{Function argument constraint is not satisfied}} \
34 // bugpath-note{{Function argument constraint is not satisfied}}
35 (void)ret;
36}
37
38void test_alnum_symbolic(int x) {
39 int ret = isalnum(x);
40 (void)ret;
41
42 clang_analyzer_eval(EOF <= x && x <= 255); // \
43 // report-warning{{TRUE}} \
44 // bugpath-warning{{TRUE}} \
45 // bugpath-note{{TRUE}} \
46 // bugpath-note{{Left side of '&&' is true}} \
47 // bugpath-note{{'x' is <= 255}}
Gabor Marton94061df2020-03-20 16:20:53 +010048}
49
50void test_alnum_symbolic2(int x) {
51 if (x > 255) { // \
52 // bugpath-note{{Assuming 'x' is > 255}} \
53 // bugpath-note{{Taking true branch}}
54
55 int ret = isalnum(x); // \
56 // report-warning{{Function argument constraint is not satisfied}} \
57 // bugpath-warning{{Function argument constraint is not satisfied}} \
58 // bugpath-note{{Function argument constraint is not satisfied}}
59
60 (void)ret;
61 }
62}
Gabor Martonededa652020-03-20 17:23:23 +010063
Zurab Tsinadze25bbe232020-08-12 16:18:42 +020064int toupper(int);
65
66void test_toupper_concrete(int v) {
67 int ret = toupper(256); // \
68 // report-warning{{Function argument constraint is not satisfied}} \
69 // bugpath-warning{{Function argument constraint is not satisfied}} \
70 // bugpath-note{{Function argument constraint is not satisfied}}
71 (void)ret;
72}
73
74void test_toupper_symbolic(int x) {
75 int ret = toupper(x);
76 (void)ret;
77
78 clang_analyzer_eval(EOF <= x && x <= 255); // \
79 // report-warning{{TRUE}} \
80 // bugpath-warning{{TRUE}} \
81 // bugpath-note{{TRUE}} \
82 // bugpath-note{{Left side of '&&' is true}} \
83 // bugpath-note{{'x' is <= 255}}
84}
85
86void test_toupper_symbolic2(int x) {
87 if (x > 255) { // \
88 // bugpath-note{{Assuming 'x' is > 255}} \
89 // bugpath-note{{Taking true branch}}
90
91 int ret = toupper(x); // \
92 // report-warning{{Function argument constraint is not satisfied}} \
93 // bugpath-warning{{Function argument constraint is not satisfied}} \
94 // bugpath-note{{Function argument constraint is not satisfied}}
95
96 (void)ret;
97 }
98}
99
100int tolower(int);
101
102void test_tolower_concrete(int v) {
103 int ret = tolower(256); // \
104 // report-warning{{Function argument constraint is not satisfied}} \
105 // bugpath-warning{{Function argument constraint is not satisfied}} \
106 // bugpath-note{{Function argument constraint is not satisfied}}
107 (void)ret;
108}
109
110void test_tolower_symbolic(int x) {
111 int ret = tolower(x);
112 (void)ret;
113
114 clang_analyzer_eval(EOF <= x && x <= 255); // \
115 // report-warning{{TRUE}} \
116 // bugpath-warning{{TRUE}} \
117 // bugpath-note{{TRUE}} \
118 // bugpath-note{{Left side of '&&' is true}} \
119 // bugpath-note{{'x' is <= 255}}
120}
121
122void test_tolower_symbolic2(int x) {
123 if (x > 255) { // \
124 // bugpath-note{{Assuming 'x' is > 255}} \
125 // bugpath-note{{Taking true branch}}
126
127 int ret = tolower(x); // \
128 // report-warning{{Function argument constraint is not satisfied}} \
129 // bugpath-warning{{Function argument constraint is not satisfied}} \
130 // bugpath-note{{Function argument constraint is not satisfied}}
131
132 (void)ret;
133 }
134}
135
136int toascii(int);
137
138void test_toascii_concrete(int v) {
139 int ret = toascii(256); // \
140 // report-warning{{Function argument constraint is not satisfied}} \
141 // bugpath-warning{{Function argument constraint is not satisfied}} \
142 // bugpath-note{{Function argument constraint is not satisfied}}
143 (void)ret;
144}
145
146void test_toascii_symbolic(int x) {
147 int ret = toascii(x);
148 (void)ret;
149
150 clang_analyzer_eval(EOF <= x && x <= 255); // \
151 // report-warning{{TRUE}} \
152 // bugpath-warning{{TRUE}} \
153 // bugpath-note{{TRUE}} \
154 // bugpath-note{{Left side of '&&' is true}} \
155 // bugpath-note{{'x' is <= 255}}
156}
157
158void test_toascii_symbolic2(int x) {
159 if (x > 255) { // \
160 // bugpath-note{{Assuming 'x' is > 255}} \
161 // bugpath-note{{Taking true branch}}
162
163 int ret = toascii(x); // \
164 // report-warning{{Function argument constraint is not satisfied}} \
165 // bugpath-warning{{Function argument constraint is not satisfied}} \
166 // bugpath-note{{Function argument constraint is not satisfied}}
167
168 (void)ret;
169 }
170}
171
Gabor Martonededa652020-03-20 17:23:23 +0100172typedef struct FILE FILE;
173typedef typeof(sizeof(int)) size_t;
Gabor Marton634258b2020-05-15 11:25:40 +0200174size_t fread(void *restrict, size_t, size_t, FILE *restrict);
Gabor Martonededa652020-03-20 17:23:23 +0100175void test_notnull_concrete(FILE *fp) {
176 fread(0, sizeof(int), 10, fp); // \
177 // report-warning{{Function argument constraint is not satisfied}} \
178 // bugpath-warning{{Function argument constraint is not satisfied}} \
179 // bugpath-note{{Function argument constraint is not satisfied}}
180}
181void test_notnull_symbolic(FILE *fp, int *buf) {
182 fread(buf, sizeof(int), 10, fp);
183 clang_analyzer_eval(buf != 0); // \
184 // report-warning{{TRUE}} \
185 // bugpath-warning{{TRUE}} \
186 // bugpath-note{{TRUE}} \
187 // bugpath-note{{'buf' is not equal to null}}
188}
189void test_notnull_symbolic2(FILE *fp, int *buf) {
Zurab Tsinadze25bbe232020-08-12 16:18:42 +0200190 if (!buf) // bugpath-note{{Assuming 'buf' is null}} \
Gabor Martonededa652020-03-20 17:23:23 +0100191 // bugpath-note{{Taking true branch}}
192 fread(buf, sizeof(int), 10, fp); // \
193 // report-warning{{Function argument constraint is not satisfied}} \
194 // bugpath-warning{{Function argument constraint is not satisfied}} \
195 // bugpath-note{{Function argument constraint is not satisfied}}
196}
Gabor Martona012bc42020-09-03 13:23:49 +0200197typedef __WCHAR_TYPE__ wchar_t;
198// This is one test case for the ARR38-C SEI-CERT rule.
199void ARR38_C_F(FILE *file) {
200 enum { BUFFER_SIZE = 1024 };
201 wchar_t wbuf[BUFFER_SIZE]; // bugpath-note{{'wbuf' initialized here}}
202
203 const size_t size = sizeof(*wbuf);
204 const size_t nitems = sizeof(wbuf);
205
206 // The 3rd parameter should be the number of elements to read, not
207 // the size in bytes.
208 fread(wbuf, size, nitems, file); // \
209 // report-warning{{Function argument constraint is not satisfied}} \
210 // bugpath-warning{{Function argument constraint is not satisfied}} \
211 // bugpath-note{{Function argument constraint is not satisfied}}
212}
Gabor Marton15252322020-04-02 16:59:02 +0200213
214int __two_constrained_args(int, int);
215void test_constraints_on_multiple_args(int x, int y) {
216 // State split should not happen here. I.e. x == 1 should not be evaluated
217 // FALSE.
218 __two_constrained_args(x, y);
219 clang_analyzer_eval(x == 1); // \
220 // report-warning{{TRUE}} \
221 // bugpath-warning{{TRUE}} \
222 // bugpath-note{{TRUE}}
223 clang_analyzer_eval(y == 1); // \
224 // report-warning{{TRUE}} \
225 // bugpath-warning{{TRUE}} \
226 // bugpath-note{{TRUE}}
227}
228
229int __arg_constrained_twice(int);
230void test_multiple_constraints_on_same_arg(int x) {
231 __arg_constrained_twice(x);
232 // Check that both constraints are applied and only one branch is there.
233 clang_analyzer_eval(x < 1 || x > 2); // \
234 // report-warning{{TRUE}} \
235 // bugpath-warning{{TRUE}} \
236 // bugpath-note{{TRUE}} \
237 // bugpath-note{{Assuming 'x' is < 1}} \
238 // bugpath-note{{Left side of '||' is true}}
239}
Gabor Marton8f961392020-04-03 17:01:00 +0200240
241int __variadic(void *stream, const char *format, ...);
242void test_arg_constraint_on_variadic_fun() {
243 __variadic(0, "%d%d", 1, 2); // \
244 // report-warning{{Function argument constraint is not satisfied}} \
245 // bugpath-warning{{Function argument constraint is not satisfied}} \
246 // bugpath-note{{Function argument constraint is not satisfied}}
247}
Gabor Martonbd03ef12020-03-30 17:47:48 +0200248
249int __buf_size_arg_constraint(const void *, size_t);
250void test_buf_size_concrete() {
251 char buf[3]; // bugpath-note{{'buf' initialized here}}
252 __buf_size_arg_constraint(buf, 4); // \
253 // report-warning{{Function argument constraint is not satisfied}} \
254 // bugpath-warning{{Function argument constraint is not satisfied}} \
255 // bugpath-note{{Function argument constraint is not satisfied}}
256}
257void test_buf_size_symbolic(int s) {
258 char buf[3];
259 __buf_size_arg_constraint(buf, s);
260 clang_analyzer_eval(s <= 3); // \
261 // report-warning{{TRUE}} \
262 // bugpath-warning{{TRUE}} \
263 // bugpath-note{{TRUE}} \
264 // bugpath-note{{'s' is <= 3}}
265}
266void test_buf_size_symbolic_and_offset(int s) {
267 char buf[3];
268 __buf_size_arg_constraint(buf + 1, s);
269 clang_analyzer_eval(s <= 2); // \
270 // report-warning{{TRUE}} \
271 // bugpath-warning{{TRUE}} \
272 // bugpath-note{{TRUE}} \
273 // bugpath-note{{'s' is <= 2}}
274}
Gabor Martonf0b9dbc2020-07-21 18:50:43 +0200275
Gabor Marton41928c92020-03-31 17:41:10 +0200276int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
277void test_buf_size_concrete_with_multiplication() {
Zurab Tsinadze25bbe232020-08-12 16:18:42 +0200278 short buf[3]; // bugpath-note{{'buf' initialized here}}
Gabor Marton41928c92020-03-31 17:41:10 +0200279 __buf_size_arg_constraint_mul(buf, 4, sizeof(short)); // \
280 // report-warning{{Function argument constraint is not satisfied}} \
281 // bugpath-warning{{Function argument constraint is not satisfied}} \
282 // bugpath-note{{Function argument constraint is not satisfied}}
283}
284void test_buf_size_symbolic_with_multiplication(size_t s) {
285 short buf[3];
286 __buf_size_arg_constraint_mul(buf, s, sizeof(short));
287 clang_analyzer_eval(s * sizeof(short) <= 6); // \
288 // report-warning{{TRUE}} \
289 // bugpath-warning{{TRUE}} \
290 // bugpath-note{{TRUE}}
291}
292void test_buf_size_symbolic_and_offset_with_multiplication(size_t s) {
293 short buf[3];
294 __buf_size_arg_constraint_mul(buf + 1, s, sizeof(short));
295 clang_analyzer_eval(s * sizeof(short) <= 4); // \
296 // report-warning{{TRUE}} \
297 // bugpath-warning{{TRUE}} \
298 // bugpath-note{{TRUE}}
299}
Gabor Martonf0b9dbc2020-07-21 18:50:43 +0200300
301// The minimum buffer size for this function is set to 10.
302int __buf_size_arg_constraint_concrete(const void *);
303void test_min_buf_size() {
304 char buf[9];// bugpath-note{{'buf' initialized here}}
305 __buf_size_arg_constraint_concrete(buf); // \
306 // report-warning{{Function argument constraint is not satisfied}} \
307 // bugpath-warning{{Function argument constraint is not satisfied}} \
308 // bugpath-note{{Function argument constraint is not satisfied}}
309}