1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
2 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
3 // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
4 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
5
6 //===----------------------------------------------------------------------===
7 // Declarations
8 //===----------------------------------------------------------------------===
9
10 // Some functions are so similar to each other that they follow the same code
11 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
12 // defined, make sure to use the variants instead to make sure they are still
13 // checked by the analyzer.
14
15 // Some functions are implemented as builtins. These should be #defined as
16 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
17
18 // Functions that have variants and are also available as builtins should be
19 // declared carefully! See memcpy() for an example.
20
21 #ifdef USE_BUILTINS
22 # define BUILTIN(f) __builtin_ ## f
23 #else /* USE_BUILTINS */
24 # define BUILTIN(f) f
25 #endif /* USE_BUILTINS */
26
27 typedef typeof(sizeof(int)) size_t;
28
29 void clang_analyzer_eval(int);
30
31 //===----------------------------------------------------------------------===
32 // memcpy()
33 //===----------------------------------------------------------------------===
34
35 #ifdef VARIANT
36
37 #define __memcpy_chk BUILTIN(__memcpy_chk)
38 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
39 size_t destlen);
40
41 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
42
43 #else /* VARIANT */
44
45 #define memcpy BUILTIN(memcpy)
46 void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
47
48 #endif /* VARIANT */
49
50
memcpy0()51 void memcpy0 () {
52 char src[] = {1, 2, 3, 4};
53 char dst[4] = {0};
54
55 memcpy(dst, src, 4); // no-warning
56
57 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
58
59 // If we actually model the copy, we can make this known.
60 // The important thing for now is that the old value has been invalidated.
61 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
62 }
63
memcpy1()64 void memcpy1 () {
65 char src[] = {1, 2, 3, 4};
66 char dst[10];
67
68 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
69 }
70
memcpy2()71 void memcpy2 () {
72 char src[] = {1, 2, 3, 4};
73 char dst[1];
74
75 memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
76 }
77
memcpy3()78 void memcpy3 () {
79 char src[] = {1, 2, 3, 4};
80 char dst[3];
81
82 memcpy(dst+1, src+2, 2); // no-warning
83 }
84
memcpy4()85 void memcpy4 () {
86 char src[] = {1, 2, 3, 4};
87 char dst[10];
88
89 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
90 }
91
memcpy5()92 void memcpy5() {
93 char src[] = {1, 2, 3, 4};
94 char dst[3];
95
96 memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
97 }
98
memcpy6()99 void memcpy6() {
100 int a[4] = {0};
101 memcpy(a, a, 8); // expected-warning{{overlapping}}
102 }
103
memcpy7()104 void memcpy7() {
105 int a[4] = {0};
106 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
107 }
108
memcpy8()109 void memcpy8() {
110 int a[4] = {0};
111 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
112 }
113
memcpy9()114 void memcpy9() {
115 int a[4] = {0};
116 memcpy(a+2, a+1, 4); // no-warning
117 memcpy(a+1, a+2, 4); // no-warning
118 }
119
memcpy10()120 void memcpy10() {
121 char a[4] = {0};
122 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
123 }
124
memcpy11()125 void memcpy11() {
126 char a[4] = {0};
127 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
128 }
129
memcpy12()130 void memcpy12() {
131 char a[4] = {0};
132 memcpy(0, a, 0); // no-warning
133 }
134
memcpy13()135 void memcpy13() {
136 char a[4] = {0};
137 memcpy(a, 0, 0); // no-warning
138 }
139
memcpy_unknown_size(size_t n)140 void memcpy_unknown_size (size_t n) {
141 char a[4], b[4] = {1};
142 clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
143 }
144
memcpy_unknown_size_warn(size_t n)145 void memcpy_unknown_size_warn (size_t n) {
146 char a[4];
147 void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
148 clang_analyzer_eval(result == a); // no-warning (above is fatal)
149 }
150
151 //===----------------------------------------------------------------------===
152 // mempcpy()
153 //===----------------------------------------------------------------------===
154
155 #ifdef VARIANT
156
157 #define __mempcpy_chk BUILTIN(__mempcpy_chk)
158 void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
159 size_t destlen);
160
161 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
162
163 #else /* VARIANT */
164
165 #define mempcpy BUILTIN(mempcpy)
166 void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
167
168 #endif /* VARIANT */
169
170
mempcpy0()171 void mempcpy0 () {
172 char src[] = {1, 2, 3, 4};
173 char dst[5] = {0};
174
175 mempcpy(dst, src, 4); // no-warning
176
177 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
178
179 // If we actually model the copy, we can make this known.
180 // The important thing for now is that the old value has been invalidated.
181 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
182 }
183
mempcpy1()184 void mempcpy1 () {
185 char src[] = {1, 2, 3, 4};
186 char dst[10];
187
188 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
189 }
190
mempcpy2()191 void mempcpy2 () {
192 char src[] = {1, 2, 3, 4};
193 char dst[1];
194
195 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
196 }
197
mempcpy3()198 void mempcpy3 () {
199 char src[] = {1, 2, 3, 4};
200 char dst[3];
201
202 mempcpy(dst+1, src+2, 2); // no-warning
203 }
204
mempcpy4()205 void mempcpy4 () {
206 char src[] = {1, 2, 3, 4};
207 char dst[10];
208
209 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
210 }
211
mempcpy5()212 void mempcpy5() {
213 char src[] = {1, 2, 3, 4};
214 char dst[3];
215
216 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
217 }
218
mempcpy6()219 void mempcpy6() {
220 int a[4] = {0};
221 mempcpy(a, a, 8); // expected-warning{{overlapping}}
222 }
223
mempcpy7()224 void mempcpy7() {
225 int a[4] = {0};
226 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
227 }
228
mempcpy8()229 void mempcpy8() {
230 int a[4] = {0};
231 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
232 }
233
mempcpy9()234 void mempcpy9() {
235 int a[4] = {0};
236 mempcpy(a+2, a+1, 4); // no-warning
237 mempcpy(a+1, a+2, 4); // no-warning
238 }
239
mempcpy10()240 void mempcpy10() {
241 char a[4] = {0};
242 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
243 }
244
mempcpy11()245 void mempcpy11() {
246 char a[4] = {0};
247 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
248 }
249
mempcpy12()250 void mempcpy12() {
251 char a[4] = {0};
252 mempcpy(0, a, 0); // no-warning
253 }
254
mempcpy13()255 void mempcpy13() {
256 char a[4] = {0};
257 mempcpy(a, 0, 0); // no-warning
258 }
259
mempcpy14()260 void mempcpy14() {
261 int src[] = {1, 2, 3, 4};
262 int dst[5] = {0};
263 int *p;
264
265 p = mempcpy(dst, src, 4 * sizeof(int));
266
267 clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}
268 }
269
270 struct st {
271 int i;
272 int j;
273 };
274
mempcpy15()275 void mempcpy15() {
276 struct st s1 = {0};
277 struct st s2;
278 struct st *p1;
279 struct st *p2;
280
281 p1 = (&s2) + 1;
282 p2 = mempcpy(&s2, &s1, sizeof(struct st));
283
284 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
285 }
286
mempcpy16()287 void mempcpy16() {
288 struct st s1[10] = {{0}};
289 struct st s2[10];
290 struct st *p1;
291 struct st *p2;
292
293 p1 = (&s2[0]) + 5;
294 p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st));
295
296 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
297 }
298
mempcpy_unknown_size_warn(size_t n)299 void mempcpy_unknown_size_warn (size_t n) {
300 char a[4];
301 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
302 clang_analyzer_eval(result == a); // no-warning (above is fatal)
303 }
304
mempcpy_unknownable_size(char * src,float n)305 void mempcpy_unknownable_size (char *src, float n) {
306 char a[4];
307 // This used to crash because we don't model floats.
308 mempcpy(a, src, (size_t)n);
309 }
310
311 //===----------------------------------------------------------------------===
312 // memmove()
313 //===----------------------------------------------------------------------===
314
315 #ifdef VARIANT
316
317 #define __memmove_chk BUILTIN(__memmove_chk)
318 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
319
320 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
321
322 #else /* VARIANT */
323
324 #define memmove BUILTIN(memmove)
325 void *memmove(void *s1, const void *s2, size_t n);
326
327 #endif /* VARIANT */
328
329
memmove0()330 void memmove0 () {
331 char src[] = {1, 2, 3, 4};
332 char dst[4] = {0};
333
334 memmove(dst, src, 4); // no-warning
335
336 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
337
338 // If we actually model the copy, we can make this known.
339 // The important thing for now is that the old value has been invalidated.
340 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
341 }
342
memmove1()343 void memmove1 () {
344 char src[] = {1, 2, 3, 4};
345 char dst[10];
346
347 memmove(dst, src, 5); // expected-warning{{out-of-bound}}
348 }
349
memmove2()350 void memmove2 () {
351 char src[] = {1, 2, 3, 4};
352 char dst[1];
353
354 memmove(dst, src, 4); // expected-warning{{overflow}}
355 }
356
357 //===----------------------------------------------------------------------===
358 // memcmp()
359 //===----------------------------------------------------------------------===
360
361 #ifdef VARIANT
362
363 #define bcmp BUILTIN(bcmp)
364 // __builtin_bcmp is not defined with const in Builtins.def.
365 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
366 #define memcmp bcmp
367 //
368 #else /* VARIANT */
369
370 #define memcmp BUILTIN(memcmp)
371 int memcmp(const void *s1, const void *s2, size_t n);
372
373 #endif /* VARIANT */
374
375
memcmp0()376 void memcmp0 () {
377 char a[] = {1, 2, 3, 4};
378 char b[4] = { 0 };
379
380 memcmp(a, b, 4); // no-warning
381 }
382
memcmp1()383 void memcmp1 () {
384 char a[] = {1, 2, 3, 4};
385 char b[10] = { 0 };
386
387 memcmp(a, b, 5); // expected-warning{{out-of-bound}}
388 }
389
memcmp2()390 void memcmp2 () {
391 char a[] = {1, 2, 3, 4};
392 char b[1] = { 0 };
393
394 memcmp(a, b, 4); // expected-warning{{out-of-bound}}
395 }
396
memcmp3()397 void memcmp3 () {
398 char a[] = {1, 2, 3, 4};
399
400 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
401 }
402
memcmp4(char * input)403 void memcmp4 (char *input) {
404 char a[] = {1, 2, 3, 4};
405
406 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
407 }
408
memcmp5(char * input)409 void memcmp5 (char *input) {
410 char a[] = {1, 2, 3, 4};
411
412 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
413 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
414 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
415 }
416
memcmp6(char * a,char * b,size_t n)417 void memcmp6 (char *a, char *b, size_t n) {
418 int result = memcmp(a, b, n);
419 if (result != 0)
420 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
421 // else
422 // analyzer_assert_unknown(n == 0);
423
424 // We can't do the above comparison because n has already been constrained.
425 // On one path n == 0, on the other n != 0.
426 }
427
memcmp7(char * a,size_t x,size_t y,size_t n)428 int memcmp7 (char *a, size_t x, size_t y, size_t n) {
429 // We used to crash when either of the arguments was unknown.
430 return memcmp(a, &a[x*y], n) +
431 memcmp(&a[x*y], a, n);
432 }
433
434 //===----------------------------------------------------------------------===
435 // bcopy()
436 //===----------------------------------------------------------------------===
437
438 #define bcopy BUILTIN(bcopy)
439 // __builtin_bcopy is not defined with const in Builtins.def.
440 void bcopy(/*const*/ void *s1, void *s2, size_t n);
441
442
bcopy0()443 void bcopy0 () {
444 char src[] = {1, 2, 3, 4};
445 char dst[4] = {0};
446
447 bcopy(src, dst, 4); // no-warning
448
449 // If we actually model the copy, we can make this known.
450 // The important thing for now is that the old value has been invalidated.
451 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
452 }
453
bcopy1()454 void bcopy1 () {
455 char src[] = {1, 2, 3, 4};
456 char dst[10];
457
458 bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
459 }
460
bcopy2()461 void bcopy2 () {
462 char src[] = {1, 2, 3, 4};
463 char dst[1];
464
465 bcopy(src, dst, 4); // expected-warning{{overflow}}
466 }
467
468 void *malloc(size_t);
469 void free(void *);
radar_11125445_memcopythenlogfirstbyte(const char * input,size_t length)470 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) {
471 char *bytes = malloc(sizeof(char) * (length + 1));
472 memcpy(bytes, input, length);
473 char x = bytes[0]; // no warning
474 free(bytes);
475 return x;
476 }
477