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
8 //
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
16 //
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
24 //
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
32
33 //===----------------------------------------------------------------------===
34 // Declarations
35 //===----------------------------------------------------------------------===
36
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.
41
42 // Some functions are implemented as builtins. These should be #defined as
43 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
44
45 // Functions that have variants and are also available as builtins should be
46 // declared carefully! See memcpy() for an example.
47
48 #ifdef USE_BUILTINS
49 # define BUILTIN(f) __builtin_ ## f
50 #else /* USE_BUILTINS */
51 # define BUILTIN(f) f
52 #endif /* USE_BUILTINS */
53
54 typedef typeof(sizeof(int)) size_t;
55
56 void clang_analyzer_eval(int);
57
58 //===----------------------------------------------------------------------===
59 // memcpy()
60 //===----------------------------------------------------------------------===
61
62 #ifdef VARIANT
63
64 #define __memcpy_chk BUILTIN(__memcpy_chk)
65 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
66 size_t destlen);
67
68 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
69
70 #else /* VARIANT */
71
72 #define memcpy BUILTIN(memcpy)
73 void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
74
75 #endif /* VARIANT */
76
77
memcpy0(void)78 void memcpy0 (void) {
79 char src[] = {1, 2, 3, 4};
80 char dst[4] = {0};
81
82 memcpy(dst, src, 4); // no-warning
83
84 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
85
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}}
89 }
90
memcpy1(void)91 void memcpy1 (void) {
92 char src[] = {1, 2, 3, 4};
93 char dst[10];
94
95 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
96 }
97
memcpy2(void)98 void memcpy2 (void) {
99 char src[] = {1, 2, 3, 4};
100 char dst[1];
101
102 memcpy(dst, src, 4); // expected-warning {{Memory copy function overflows the destination buffer}}
103 #ifndef VARIANT
104 // expected-warning@-2 {{memcpy' will always overflow; destination buffer has size 1, but size argument is 4}}
105 #endif
106 }
107
memcpy3(void)108 void memcpy3 (void) {
109 char src[] = {1, 2, 3, 4};
110 char dst[3];
111
112 memcpy(dst+1, src+2, 2); // no-warning
113 }
114
memcpy4(void)115 void memcpy4 (void) {
116 char src[] = {1, 2, 3, 4};
117 char dst[10];
118
119 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
120 }
121
memcpy5(void)122 void memcpy5(void) {
123 char src[] = {1, 2, 3, 4};
124 char dst[3];
125
126 memcpy(dst + 2, src + 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}}
127 #ifndef VARIANT
128 // expected-warning@-2{{memcpy' will always overflow; destination buffer has size 1, but size argument is 2}}
129 #endif
130 }
131
memcpy6(void)132 void memcpy6(void) {
133 int a[4] = {0};
134 memcpy(a, a, 8); // expected-warning{{overlapping}}
135 }
136
memcpy7(void)137 void memcpy7(void) {
138 int a[4] = {0};
139 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
140 }
141
memcpy8(void)142 void memcpy8(void) {
143 int a[4] = {0};
144 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
145 }
146
memcpy9(void)147 void memcpy9(void) {
148 int a[4] = {0};
149 memcpy(a+2, a+1, 4); // no-warning
150 memcpy(a+1, a+2, 4); // no-warning
151 }
152
memcpy10(void)153 void memcpy10(void) {
154 char a[4] = {0};
155 memcpy(0, a, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
156 }
157
memcpy11(void)158 void memcpy11(void) {
159 char a[4] = {0};
160 memcpy(a, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
161 }
162
memcpy12(void)163 void memcpy12(void) {
164 char a[4] = {0};
165 memcpy(0, a, 0); // no-warning
166 }
167
memcpy13(void)168 void memcpy13(void) {
169 char a[4] = {0};
170 memcpy(a, 0, 0); // no-warning
171 }
172
memcpy_unknown_size(size_t n)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}}
176 }
177
memcpy_unknown_size_warn(size_t n)178 void memcpy_unknown_size_warn (size_t n) {
179 char a[4];
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)
182 }
183
184 //===----------------------------------------------------------------------===
185 // mempcpy()
186 //===----------------------------------------------------------------------===
187
188 #ifdef VARIANT
189
190 #define __mempcpy_chk BUILTIN(__mempcpy_chk)
191 void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
192 size_t destlen);
193
194 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
195
196 #else /* VARIANT */
197
198 #define mempcpy BUILTIN(mempcpy)
199 void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
200
201 #endif /* VARIANT */
202
203
mempcpy0(void)204 void mempcpy0 (void) {
205 char src[] = {1, 2, 3, 4};
206 char dst[5] = {0};
207
208 mempcpy(dst, src, 4); // no-warning
209
210 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
211
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}}
215 }
216
mempcpy1(void)217 void mempcpy1 (void) {
218 char src[] = {1, 2, 3, 4};
219 char dst[10];
220
221 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
222 }
223
mempcpy2(void)224 void mempcpy2 (void) {
225 char src[] = {1, 2, 3, 4};
226 char dst[1];
227
228 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows the destination buffer}}
229 #ifndef VARIANT
230 // expected-warning@-2{{'mempcpy' will always overflow; destination buffer has size 1, but size argument is 4}}
231 #endif
232 }
233
mempcpy3(void)234 void mempcpy3 (void) {
235 char src[] = {1, 2, 3, 4};
236 char dst[3];
237
238 mempcpy(dst+1, src+2, 2); // no-warning
239 }
240
mempcpy4(void)241 void mempcpy4 (void) {
242 char src[] = {1, 2, 3, 4};
243 char dst[10];
244
245 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
246 }
247
mempcpy5(void)248 void mempcpy5(void) {
249 char src[] = {1, 2, 3, 4};
250 char dst[3];
251
252 mempcpy(dst + 2, src + 2, 2); // expected-warning{{Memory copy function overflows the destination buffer}}
253 #ifndef VARIANT
254 // expected-warning@-2{{'mempcpy' will always overflow; destination buffer has size 1, but size argument is 2}}
255 #endif
256 }
257
mempcpy6(void)258 void mempcpy6(void) {
259 int a[4] = {0};
260 mempcpy(a, a, 8); // expected-warning{{overlapping}}
261 }
262
mempcpy7(void)263 void mempcpy7(void) {
264 int a[4] = {0};
265 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
266 }
267
mempcpy8(void)268 void mempcpy8(void) {
269 int a[4] = {0};
270 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
271 }
272
mempcpy9(void)273 void mempcpy9(void) {
274 int a[4] = {0};
275 mempcpy(a+2, a+1, 4); // no-warning
276 mempcpy(a+1, a+2, 4); // no-warning
277 }
278
mempcpy10(void)279 void mempcpy10(void) {
280 char a[4] = {0};
281 mempcpy(0, a, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
282 }
283
mempcpy11(void)284 void mempcpy11(void) {
285 char a[4] = {0};
286 mempcpy(a, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
287 }
288
mempcpy12(void)289 void mempcpy12(void) {
290 char a[4] = {0};
291 mempcpy(0, a, 0); // no-warning
292 }
293
mempcpy13(void)294 void mempcpy13(void) {
295 char a[4] = {0};
296 mempcpy(a, 0, 0); // no-warning
297 }
298
mempcpy14(void)299 void mempcpy14(void) {
300 int src[] = {1, 2, 3, 4};
301 int dst[5] = {0};
302 int *p;
303
304 p = mempcpy(dst, src, 4 * sizeof(int));
305
306 clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}
307 }
308
309 struct st {
310 int i;
311 int j;
312 };
313
mempcpy15(void)314 void mempcpy15(void) {
315 struct st s1 = {0};
316 struct st s2;
317 struct st *p1;
318 struct st *p2;
319
320 p1 = (&s2) + 1;
321 p2 = mempcpy(&s2, &s1, sizeof(struct st));
322
323 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
324 }
325
mempcpy16(void)326 void mempcpy16(void) {
327 struct st s1[10] = {{0}};
328 struct st s2[10];
329 struct st *p1;
330 struct st *p2;
331
332 p1 = (&s2[0]) + 5;
333 p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st));
334
335 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
336 }
337
mempcpy_unknown_size_warn(size_t n)338 void mempcpy_unknown_size_warn (size_t n) {
339 char a[4];
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)
342 }
343
mempcpy_unknownable_size(char * src,float n)344 void mempcpy_unknownable_size (char *src, float n) {
345 char a[4];
346 // This used to crash because we don't model floats.
347 mempcpy(a, src, (size_t)n);
348 }
349
350 //===----------------------------------------------------------------------===
351 // memmove()
352 //===----------------------------------------------------------------------===
353
354 #ifdef VARIANT
355
356 #define __memmove_chk BUILTIN(__memmove_chk)
357 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
358
359 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
360
361 #else /* VARIANT */
362
363 #define memmove BUILTIN(memmove)
364 void *memmove(void *s1, const void *s2, size_t n);
365
366 #endif /* VARIANT */
367
368
memmove0(void)369 void memmove0 (void) {
370 char src[] = {1, 2, 3, 4};
371 char dst[4] = {0};
372
373 memmove(dst, src, 4); // no-warning
374
375 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
376
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}}
380 }
381
memmove1(void)382 void memmove1 (void) {
383 char src[] = {1, 2, 3, 4};
384 char dst[10];
385
386 memmove(dst, src, 5); // expected-warning{{out-of-bound}}
387 }
388
memmove2(void)389 void memmove2 (void) {
390 char src[] = {1, 2, 3, 4};
391 char dst[1];
392
393 memmove(dst, src, 4); // expected-warning{{Memory copy function overflows the destination buffer}}
394 #ifndef VARIANT
395 // expected-warning@-2{{memmove' will always overflow; destination buffer has size 1, but size argument is 4}}
396 #endif
397 }
398
399 //===----------------------------------------------------------------------===
400 // memcmp()
401 //===----------------------------------------------------------------------===
402
403 #ifdef VARIANT
404
405 #define bcmp BUILTIN(bcmp)
406 int bcmp(const void *s1, const void *s2, size_t n);
407 #define memcmp bcmp
408 //
409 #else /* VARIANT */
410
411 #define memcmp BUILTIN(memcmp)
412 int memcmp(const void *s1, const void *s2, size_t n);
413
414 #endif /* VARIANT */
415
416
memcmp0(void)417 void memcmp0 (void) {
418 char a[] = {1, 2, 3, 4};
419 char b[4] = { 0 };
420
421 memcmp(a, b, 4); // no-warning
422 }
423
memcmp1(void)424 void memcmp1 (void) {
425 char a[] = {1, 2, 3, 4};
426 char b[10] = { 0 };
427
428 memcmp(a, b, 5); // expected-warning{{out-of-bound}}
429 }
430
memcmp2(void)431 void memcmp2 (void) {
432 char a[] = {1, 2, 3, 4};
433 char b[1] = { 0 };
434
435 memcmp(a, b, 4); // expected-warning{{out-of-bound}}
436 }
437
memcmp3(void)438 void memcmp3 (void) {
439 char a[] = {1, 2, 3, 4};
440
441 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
442 }
443
memcmp4(char * input)444 void memcmp4 (char *input) {
445 char a[] = {1, 2, 3, 4};
446
447 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
448 }
449
memcmp5(char * input)450 void memcmp5 (char *input) {
451 char a[] = {1, 2, 3, 4};
452
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}}
456 }
457
memcmp6(char * a,char * b,size_t n)458 void memcmp6 (char *a, char *b, size_t n) {
459 int result = memcmp(a, b, n);
460 if (result != 0)
461 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
462 // else
463 // analyzer_assert_unknown(n == 0);
464
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.
467 }
468
memcmp7(char * a,size_t x,size_t y,size_t n)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);
473 }
474
memcmp8(char * a,size_t n)475 int memcmp8(char *a, size_t n) {
476 char *b = 0;
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}}
479 }
480
481 //===----------------------------------------------------------------------===
482 // bcopy()
483 //===----------------------------------------------------------------------===
484
485 #define bcopy BUILTIN(bcopy)
486 void bcopy(const void *s1, void *s2, size_t n);
487
488
bcopy0(void)489 void bcopy0 (void) {
490 char src[] = {1, 2, 3, 4};
491 char dst[4] = {0};
492
493 bcopy(src, dst, 4); // no-warning
494
495 // If we actually model the copy, we can make this known.
496 // The important thing for now is that the old value has been invalidated.
497 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
498 }
499
bcopy1(void)500 void bcopy1 (void) {
501 char src[] = {1, 2, 3, 4};
502 char dst[10];
503
504 bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
505 }
506
bcopy2(void)507 void bcopy2 (void) {
508 char src[] = {1, 2, 3, 4};
509 char dst[1];
510
511 bcopy(src, dst, 4); // expected-warning{{overflow}}
512 }
513
514 void *malloc(size_t);
515 void free(void *);
radar_11125445_memcopythenlogfirstbyte(const char * input,size_t length)516 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) {
517 char *bytes = malloc(sizeof(char) * (length + 1));
518 memcpy(bytes, input, length);
519 char x = bytes[0]; // no warning
520 free(bytes);
521 return x;
522 }
523
524 struct S {
525 char f;
526 };
527
nocrash_on_locint_offset(void * addr,void * from,struct S s)528 void nocrash_on_locint_offset(void *addr, void* from, struct S s) {
529 size_t iAdd = (size_t) addr;
530 memcpy(((void *) &(s.f)), from, iAdd);
531 }
532