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 
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 
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 
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 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 
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 
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 
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 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 
128 void memcpy6() {
129   int a[4] = {0};
130   memcpy(a, a, 8); // expected-warning{{overlapping}}
131 }
132 
133 void memcpy7() {
134   int a[4] = {0};
135   memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
136 }
137 
138 void memcpy8() {
139   int a[4] = {0};
140   memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
141 }
142 
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 
149 void memcpy10() {
150   char a[4] = {0};
151   memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
152 }
153 
154 void memcpy11() {
155   char a[4] = {0};
156   memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
157 }
158 
159 void memcpy12() {
160   char a[4] = {0};
161   memcpy(0, a, 0); // no-warning
162 }
163 
164 void memcpy13() {
165   char a[4] = {0};
166   memcpy(a, 0, 0); // no-warning
167 }
168 
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 
174 void memcpy_unknown_size_warn (size_t n) {
175   char a[4];
176   void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call 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 
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 
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 
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 destination buffer}}
225 }
226 
227 void mempcpy3 () {
228   char src[] = {1, 2, 3, 4};
229   char dst[3];
230 
231   mempcpy(dst+1, src+2, 2); // no-warning
232 }
233 
234 void mempcpy4 () {
235   char src[] = {1, 2, 3, 4};
236   char dst[10];
237 
238   mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
239 }
240 
241 void mempcpy5() {
242   char src[] = {1, 2, 3, 4};
243   char dst[3];
244 
245   mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
246 }
247 
248 void mempcpy6() {
249   int a[4] = {0};
250   mempcpy(a, a, 8); // expected-warning{{overlapping}}
251 }
252 
253 void mempcpy7() {
254   int a[4] = {0};
255   mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
256 }
257 
258 void mempcpy8() {
259   int a[4] = {0};
260   mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
261 }
262 
263 void mempcpy9() {
264   int a[4] = {0};
265   mempcpy(a+2, a+1, 4); // no-warning
266   mempcpy(a+1, a+2, 4); // no-warning
267 }
268 
269 void mempcpy10() {
270   char a[4] = {0};
271   mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
272 }
273 
274 void mempcpy11() {
275   char a[4] = {0};
276   mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
277 }
278 
279 void mempcpy12() {
280   char a[4] = {0};
281   mempcpy(0, a, 0); // no-warning
282 }
283 
284 void mempcpy13() {
285   char a[4] = {0};
286   mempcpy(a, 0, 0); // no-warning
287 }
288 
289 void mempcpy14() {
290   int src[] = {1, 2, 3, 4};
291   int dst[5] = {0};
292   int *p;
293 
294   p = mempcpy(dst, src, 4 * sizeof(int));
295 
296   clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}
297 }
298 
299 struct st {
300   int i;
301   int j;
302 };
303 
304 void mempcpy15() {
305   struct st s1 = {0};
306   struct st s2;
307   struct st *p1;
308   struct st *p2;
309 
310   p1 = (&s2) + 1;
311   p2 = mempcpy(&s2, &s1, sizeof(struct st));
312 
313   clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
314 }
315 
316 void mempcpy16() {
317   struct st s1[10] = {{0}};
318   struct st s2[10];
319   struct st *p1;
320   struct st *p2;
321 
322   p1 = (&s2[0]) + 5;
323   p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st));
324 
325   clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
326 }
327 
328 void mempcpy_unknown_size_warn (size_t n) {
329   char a[4];
330   void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
331   clang_analyzer_eval(result == a); // no-warning (above is fatal)
332 }
333 
334 void mempcpy_unknownable_size (char *src, float n) {
335   char a[4];
336   // This used to crash because we don't model floats.
337   mempcpy(a, src, (size_t)n);
338 }
339 
340 //===----------------------------------------------------------------------===
341 // memmove()
342 //===----------------------------------------------------------------------===
343 
344 #ifdef VARIANT
345 
346 #define __memmove_chk BUILTIN(__memmove_chk)
347 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
348 
349 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
350 
351 #else /* VARIANT */
352 
353 #define memmove BUILTIN(memmove)
354 void *memmove(void *s1, const void *s2, size_t n);
355 
356 #endif /* VARIANT */
357 
358 
359 void memmove0 () {
360   char src[] = {1, 2, 3, 4};
361   char dst[4] = {0};
362 
363   memmove(dst, src, 4); // no-warning
364 
365   clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
366 
367   // If we actually model the copy, we can make this known.
368   // The important thing for now is that the old value has been invalidated.
369   clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
370 }
371 
372 void memmove1 () {
373   char src[] = {1, 2, 3, 4};
374   char dst[10];
375 
376   memmove(dst, src, 5); // expected-warning{{out-of-bound}}
377 }
378 
379 void memmove2 () {
380   char src[] = {1, 2, 3, 4};
381   char dst[1];
382 
383   memmove(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
384 #ifndef VARIANT
385   // expected-warning@-2{{memmove' will always overflow; destination buffer has size 1, but size argument is 4}}
386 #endif
387 }
388 
389 //===----------------------------------------------------------------------===
390 // memcmp()
391 //===----------------------------------------------------------------------===
392 
393 #ifdef VARIANT
394 
395 #define bcmp BUILTIN(bcmp)
396 int bcmp(const void *s1, const void *s2, size_t n);
397 #define memcmp bcmp
398 //
399 #else /* VARIANT */
400 
401 #define memcmp BUILTIN(memcmp)
402 int memcmp(const void *s1, const void *s2, size_t n);
403 
404 #endif /* VARIANT */
405 
406 
407 void memcmp0 () {
408   char a[] = {1, 2, 3, 4};
409   char b[4] = { 0 };
410 
411   memcmp(a, b, 4); // no-warning
412 }
413 
414 void memcmp1 () {
415   char a[] = {1, 2, 3, 4};
416   char b[10] = { 0 };
417 
418   memcmp(a, b, 5); // expected-warning{{out-of-bound}}
419 }
420 
421 void memcmp2 () {
422   char a[] = {1, 2, 3, 4};
423   char b[1] = { 0 };
424 
425   memcmp(a, b, 4); // expected-warning{{out-of-bound}}
426 }
427 
428 void memcmp3 () {
429   char a[] = {1, 2, 3, 4};
430 
431   clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
432 }
433 
434 void memcmp4 (char *input) {
435   char a[] = {1, 2, 3, 4};
436 
437   clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
438 }
439 
440 void memcmp5 (char *input) {
441   char a[] = {1, 2, 3, 4};
442 
443   clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
444   clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
445   clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
446 }
447 
448 void memcmp6 (char *a, char *b, size_t n) {
449   int result = memcmp(a, b, n);
450   if (result != 0)
451     clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
452   // else
453   //   analyzer_assert_unknown(n == 0);
454 
455   // We can't do the above comparison because n has already been constrained.
456   // On one path n == 0, on the other n != 0.
457 }
458 
459 int memcmp7 (char *a, size_t x, size_t y, size_t n) {
460   // We used to crash when either of the arguments was unknown.
461   return memcmp(a, &a[x*y], n) +
462          memcmp(&a[x*y], a, n);
463 }
464 
465 //===----------------------------------------------------------------------===
466 // bcopy()
467 //===----------------------------------------------------------------------===
468 
469 #define bcopy BUILTIN(bcopy)
470 // __builtin_bcopy is not defined with const in Builtins.def.
471 void bcopy(/*const*/ void *s1, void *s2, size_t n);
472 
473 
474 void bcopy0 () {
475   char src[] = {1, 2, 3, 4};
476   char dst[4] = {0};
477 
478   bcopy(src, dst, 4); // no-warning
479 
480   // If we actually model the copy, we can make this known.
481   // The important thing for now is that the old value has been invalidated.
482   clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
483 }
484 
485 void bcopy1 () {
486   char src[] = {1, 2, 3, 4};
487   char dst[10];
488 
489   bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
490 }
491 
492 void bcopy2 () {
493   char src[] = {1, 2, 3, 4};
494   char dst[1];
495 
496   bcopy(src, dst, 4); // expected-warning{{overflow}}
497 }
498 
499 void *malloc(size_t);
500 void free(void *);
501 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) {
502   char *bytes = malloc(sizeof(char) * (length + 1));
503   memcpy(bytes, input, length);
504   char x = bytes[0]; // no warning
505   free(bytes);
506   return x;
507 }
508 
509 struct S {
510   char f;
511 };
512 
513 void nocrash_on_locint_offset(void *addr, void* from, struct S s) {
514   int iAdd = (int) addr;
515   memcpy(((void *) &(s.f)), from, iAdd);
516 }
517