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