1 // RUN: %clang_analyze_cc1 -verify %s \
2 // RUN: -analyzer-checker=core \
3 // RUN: -analyzer-checker=unix.cstring \
4 // RUN: -analyzer-checker=alpha.unix.cstring \
5 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \
6 // RUN: -analyzer-checker=debug.ExprInspection \
7 // RUN: -analyzer-config eagerly-assume=false
9 // RUN: %clang_analyze_cc1 -verify %s -DUSE_BUILTINS \
10 // RUN: -analyzer-checker=core \
11 // RUN: -analyzer-checker=unix.cstring \
12 // RUN: -analyzer-checker=alpha.unix.cstring \
13 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \
14 // RUN: -analyzer-checker=debug.ExprInspection \
15 // RUN: -analyzer-config eagerly-assume=false
17 // RUN: %clang_analyze_cc1 -verify %s -DVARIANT \
18 // RUN: -analyzer-checker=core \
19 // RUN: -analyzer-checker=unix.cstring \
20 // RUN: -analyzer-checker=alpha.unix.cstring \
21 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \
22 // RUN: -analyzer-checker=debug.ExprInspection \
23 // RUN: -analyzer-config eagerly-assume=false
25 // RUN: %clang_analyze_cc1 -verify %s -DUSE_BUILTINS -DVARIANT \
26 // RUN: -analyzer-checker=core \
27 // RUN: -analyzer-checker=unix.cstring \
28 // RUN: -analyzer-checker=alpha.unix.cstring \
29 // RUN: -analyzer-disable-checker=alpha.unix.cstring.UninitializedRead \
30 // RUN: -analyzer-checker=debug.ExprInspection \
31 // RUN: -analyzer-config eagerly-assume=false
33 //===----------------------------------------------------------------------===
35 //===----------------------------------------------------------------------===
37 // Some functions are so similar to each other that they follow the same code
38 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
39 // defined, make sure to use the variants instead to make sure they are still
40 // checked by the analyzer.
42 // Some functions are implemented as builtins. These should be #defined as
43 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
45 // Functions that have variants and are also available as builtins should be
46 // declared carefully! See memcpy() for an example.
49 # define BUILTIN(f) __builtin_ ## f
50 #else /* USE_BUILTINS */
52 #endif /* USE_BUILTINS */
54 typedef typeof(sizeof(int)) size_t;
56 void clang_analyzer_eval(int);
58 //===----------------------------------------------------------------------===
60 //===----------------------------------------------------------------------===
64 #define __memcpy_chk BUILTIN(__memcpy_chk)
65 void *__memcpy_chk(void *restrict s1
, const void *restrict s2
, size_t n
,
68 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
72 #define memcpy BUILTIN(memcpy)
73 void *memcpy(void *restrict s1
, const void *restrict s2
, size_t n
);
79 char src
[] = {1, 2, 3, 4};
82 memcpy(dst
, src
, 4); // no-warning
84 clang_analyzer_eval(memcpy(dst
, src
, 4) == dst
); // expected-warning{{TRUE}}
86 // If we actually model the copy, we can make this known.
87 // The important thing for now is that the old value has been invalidated.
88 clang_analyzer_eval(dst
[0] != 0); // expected-warning{{UNKNOWN}}
92 char src
[] = {1, 2, 3, 4};
95 memcpy(dst
, src
, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
99 char src
[] = {1, 2, 3, 4};
102 memcpy(dst
, src
, 4); // expected-warning {{Memory copy function overflows the destination buffer}}
104 // expected-warning@-2 {{memcpy' will always overflow; destination buffer has size 1, but size argument is 4}}
108 void memcpy3 (void) {
109 char src
[] = {1, 2, 3, 4};
112 memcpy(dst
+1, src
+2, 2); // no-warning
115 void memcpy4 (void) {
116 char src
[] = {1, 2, 3, 4};
119 memcpy(dst
+2, src
+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
123 char src
[] = {1, 2, 3, 4};
126 memcpy(dst
+ 2, src
+ 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}}
128 // expected-warning@-2{{memcpy' will always overflow; destination buffer has size 1, but size argument is 2}}
134 memcpy(a
, a
, 8); // expected-warning{{overlapping}}
139 memcpy(a
+2, a
+1, 8); // expected-warning{{overlapping}}
144 memcpy(a
+1, a
+2, 8); // expected-warning{{overlapping}}
149 memcpy(a
+2, a
+1, 4); // no-warning
150 memcpy(a
+1, a
+2, 4); // no-warning
153 void memcpy10(void) {
155 memcpy(0, a
, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
158 void memcpy11(void) {
160 memcpy(a
, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
163 void memcpy12(void) {
165 memcpy(0, a
, 0); // no-warning
168 void memcpy13(void) {
170 memcpy(a
, 0, 0); // no-warning
173 void memcpy_unknown_size (size_t n
) {
174 char a
[4], b
[4] = {1};
175 clang_analyzer_eval(memcpy(a
, b
, n
) == a
); // expected-warning{{TRUE}}
178 void memcpy_unknown_size_warn (size_t n
) {
180 void *result
= memcpy(a
, 0, n
); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
181 clang_analyzer_eval(result
== a
); // no-warning (above is fatal)
184 //===----------------------------------------------------------------------===
186 //===----------------------------------------------------------------------===
190 #define __mempcpy_chk BUILTIN(__mempcpy_chk)
191 void *__mempcpy_chk(void *restrict s1
, const void *restrict s2
, size_t n
,
194 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
198 #define mempcpy BUILTIN(mempcpy)
199 void *mempcpy(void *restrict s1
, const void *restrict s2
, size_t n
);
204 void mempcpy0 (void) {
205 char src
[] = {1, 2, 3, 4};
208 mempcpy(dst
, src
, 4); // no-warning
210 clang_analyzer_eval(mempcpy(dst
, src
, 4) == &dst
[4]); // expected-warning{{TRUE}}
212 // If we actually model the copy, we can make this known.
213 // The important thing for now is that the old value has been invalidated.
214 clang_analyzer_eval(dst
[0] != 0); // expected-warning{{UNKNOWN}}
217 void mempcpy1 (void) {
218 char src
[] = {1, 2, 3, 4};
221 mempcpy(dst
, src
, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
224 void mempcpy2 (void) {
225 char src
[] = {1, 2, 3, 4};
228 mempcpy(dst
, src
, 4); // expected-warning{{Memory copy function overflows the destination buffer}}
230 // expected-warning@-2{{'mempcpy' will always overflow; destination buffer has size 1, but size argument is 4}}
234 void mempcpy3 (void) {
235 char src
[] = {1, 2, 3, 4};
238 mempcpy(dst
+1, src
+2, 2); // no-warning
241 void mempcpy4 (void) {
242 char src
[] = {1, 2, 3, 4};
245 mempcpy(dst
+2, src
+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
248 void mempcpy5(void) {
249 char src
[] = {1, 2, 3, 4};
252 mempcpy(dst
+ 2, src
+ 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}}
254 // expected-warning@-2{{'mempcpy' will always overflow; destination buffer has size 1, but size argument is 2}}
258 void mempcpy6(void) {
260 mempcpy(a
, a
, 8); // expected-warning{{overlapping}}
263 void mempcpy7(void) {
265 mempcpy(a
+2, a
+1, 8); // expected-warning{{overlapping}}
268 void mempcpy8(void) {
270 mempcpy(a
+1, a
+2, 8); // expected-warning{{overlapping}}
273 void mempcpy9(void) {
275 mempcpy(a
+2, a
+1, 4); // no-warning
276 mempcpy(a
+1, a
+2, 4); // no-warning
279 void mempcpy10(void) {
281 mempcpy(0, a
, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
284 void mempcpy11(void) {
286 mempcpy(a
, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
289 void mempcpy12(void) {
291 mempcpy(0, a
, 0); // no-warning
294 void mempcpy13(void) {
296 mempcpy(a
, 0, 0); // no-warning
299 void mempcpy14(void) {
300 int src
[] = {1, 2, 3, 4};
304 p
= mempcpy(dst
, src
, 4 * sizeof(int));
306 clang_analyzer_eval(p
== &dst
[4]); // expected-warning{{TRUE}}
314 void mempcpy15(void) {
321 p2
= mempcpy(&s2
, &s1
, sizeof(struct st
));
323 clang_analyzer_eval(p1
== p2
); // expected-warning{{TRUE}}
326 void mempcpy16(void) {
327 struct st s1
[10] = {{0}};
333 p2
= mempcpy(&s2
[0], &s1
[0], 5 * sizeof(struct st
));
335 clang_analyzer_eval(p1
== p2
); // expected-warning{{TRUE}}
338 void mempcpy_unknown_size_warn (size_t n
) {
340 void *result
= mempcpy(a
, 0, n
); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
341 clang_analyzer_eval(result
== a
); // no-warning (above is fatal)
344 void mempcpy_unknownable_size (char *src
, float n
) {
346 // This used to crash because we don't model floats.
347 mempcpy(a
, src
, (size_t)n
);
350 //===----------------------------------------------------------------------===
352 //===----------------------------------------------------------------------===
356 #define __memmove_chk BUILTIN(__memmove_chk)
357 void *__memmove_chk(void *s1
, const void *s2
, size_t n
, size_t destlen
);
359 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
363 #define memmove BUILTIN(memmove)
364 void *memmove(void *s1
, const void *s2
, size_t n
);
369 void memmove0 (void) {
370 char src
[] = {1, 2, 3, 4};
373 memmove(dst
, src
, 4); // no-warning
375 clang_analyzer_eval(memmove(dst
, src
, 4) == dst
); // expected-warning{{TRUE}}
377 // If we actually model the copy, we can make this known.
378 // The important thing for now is that the old value has been invalidated.
379 clang_analyzer_eval(dst
[0] != 0); // expected-warning{{UNKNOWN}}
382 void memmove1 (void) {
383 char src
[] = {1, 2, 3, 4};
386 memmove(dst
, src
, 5); // expected-warning{{out-of-bound}}
389 void memmove2 (void) {
390 char src
[] = {1, 2, 3, 4};
393 memmove(dst
, src
, 4); // expected-warning{{Memory copy function overflows the destination buffer}}
395 // expected-warning@-2{{memmove' will always overflow; destination buffer has size 1, but size argument is 4}}
399 //===----------------------------------------------------------------------===
401 //===----------------------------------------------------------------------===
405 #define bcmp BUILTIN(bcmp)
406 int bcmp(const void *s1
, const void *s2
, size_t n
);
411 #define memcmp BUILTIN(memcmp)
412 int memcmp(const void *s1
, const void *s2
, size_t n
);
417 void memcmp0 (void) {
418 char a
[] = {1, 2, 3, 4};
421 memcmp(a
, b
, 4); // no-warning
424 void memcmp1 (void) {
425 char a
[] = {1, 2, 3, 4};
428 memcmp(a
, b
, 5); // expected-warning{{out-of-bound}}
431 void memcmp2 (void) {
432 char a
[] = {1, 2, 3, 4};
435 memcmp(a
, b
, 4); // expected-warning{{out-of-bound}}
438 void memcmp3 (void) {
439 char a
[] = {1, 2, 3, 4};
441 clang_analyzer_eval(memcmp(a
, a
, 4) == 0); // expected-warning{{TRUE}}
444 void memcmp4 (char *input
) {
445 char a
[] = {1, 2, 3, 4};
447 clang_analyzer_eval(memcmp(a
, input
, 4) == 0); // expected-warning{{UNKNOWN}}
450 void memcmp5 (char *input
) {
451 char a
[] = {1, 2, 3, 4};
453 clang_analyzer_eval(memcmp(a
, 0, 0) == 0); // expected-warning{{TRUE}}
454 clang_analyzer_eval(memcmp(0, a
, 0) == 0); // expected-warning{{TRUE}}
455 clang_analyzer_eval(memcmp(a
, input
, 0) == 0); // expected-warning{{TRUE}}
458 void memcmp6 (char *a
, char *b
, size_t n
) {
459 int result
= memcmp(a
, b
, n
);
461 clang_analyzer_eval(n
!= 0); // expected-warning{{TRUE}}
463 // analyzer_assert_unknown(n == 0);
465 // We can't do the above comparison because n has already been constrained.
466 // On one path n == 0, on the other n != 0.
469 int memcmp7 (char *a
, size_t x
, size_t y
, size_t n
) {
470 // We used to crash when either of the arguments was unknown.
471 return memcmp(a
, &a
[x
*y
], n
) +
472 memcmp(&a
[x
*y
], a
, n
);
475 int memcmp8(char *a
, size_t n
) {
477 // Do not warn about the first argument!
478 return memcmp(a
, b
, n
); // expected-warning{{Null pointer passed as 2nd argument to memory comparison function}}
481 //===----------------------------------------------------------------------===
483 //===----------------------------------------------------------------------===
485 #define bcopy BUILTIN(bcopy)
486 // __builtin_bcopy is not defined with const in Builtins.def.
487 void bcopy(/*const*/ void *s1
, void *s2
, size_t n
);
491 char src
[] = {1, 2, 3, 4};
494 bcopy(src
, dst
, 4); // no-warning
496 // If we actually model the copy, we can make this known.
497 // The important thing for now is that the old value has been invalidated.
498 clang_analyzer_eval(dst
[0] != 0); // expected-warning{{UNKNOWN}}
502 char src
[] = {1, 2, 3, 4};
505 bcopy(src
, dst
, 5); // expected-warning{{out-of-bound}}
509 char src
[] = {1, 2, 3, 4};
512 bcopy(src
, dst
, 4); // expected-warning{{overflow}}
515 void *malloc(size_t);
517 char radar_11125445_memcopythenlogfirstbyte(const char *input
, size_t length
) {
518 char *bytes
= malloc(sizeof(char) * (length
+ 1));
519 memcpy(bytes
, input
, length
);
520 char x
= bytes
[0]; // no warning
529 void nocrash_on_locint_offset(void *addr
, void* from
, struct S s
) {
530 size_t iAdd
= (size_t) addr
;
531 memcpy(((void *) &(s
.f
)), from
, iAdd
);