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