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