• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
2 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
3 // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
4 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -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 //===----------------------------------------------------------------------===
30 // memcpy()
31 //===----------------------------------------------------------------------===
32 
33 #ifdef VARIANT
34 
35 #define __memcpy_chk BUILTIN(__memcpy_chk)
36 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
37                    size_t destlen);
38 
39 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
40 
41 #else /* VARIANT */
42 
43 #define memcpy BUILTIN(memcpy)
44 void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
45 
46 #endif /* VARIANT */
47 
48 
memcpy0()49 void memcpy0 () {
50   char src[] = {1, 2, 3, 4};
51   char dst[4] = {0};
52 
53   memcpy(dst, src, 4); // no-warning
54 
55   if (memcpy(dst, src, 4) != dst) {
56     (void)*(char*)0; // no-warning
57   }
58 
59   if (dst[0] != 0)
60     (void)*(char*)0; // expected-warning{{null}}
61 }
62 
memcpy1()63 void memcpy1 () {
64   char src[] = {1, 2, 3, 4};
65   char dst[10];
66 
67   memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
68 }
69 
memcpy2()70 void memcpy2 () {
71   char src[] = {1, 2, 3, 4};
72   char dst[1];
73 
74   memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
75 }
76 
memcpy3()77 void memcpy3 () {
78   char src[] = {1, 2, 3, 4};
79   char dst[3];
80 
81   memcpy(dst+1, src+2, 2); // no-warning
82 }
83 
memcpy4()84 void memcpy4 () {
85   char src[] = {1, 2, 3, 4};
86   char dst[10];
87 
88   memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
89 }
90 
memcpy5()91 void memcpy5() {
92   char src[] = {1, 2, 3, 4};
93   char dst[3];
94 
95   memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
96 }
97 
memcpy6()98 void memcpy6() {
99   int a[4] = {0};
100   memcpy(a, a, 8); // expected-warning{{overlapping}}
101 }
102 
memcpy7()103 void memcpy7() {
104   int a[4] = {0};
105   memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
106 }
107 
memcpy8()108 void memcpy8() {
109   int a[4] = {0};
110   memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
111 }
112 
memcpy9()113 void memcpy9() {
114   int a[4] = {0};
115   memcpy(a+2, a+1, 4); // no-warning
116   memcpy(a+1, a+2, 4); // no-warning
117 }
118 
memcpy10()119 void memcpy10() {
120   char a[4] = {0};
121   memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
122 }
123 
memcpy11()124 void memcpy11() {
125   char a[4] = {0};
126   memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
127 }
128 
memcpy12()129 void memcpy12() {
130   char a[4] = {0};
131   memcpy(0, a, 0); // no-warning
132 }
133 
memcpy13()134 void memcpy13() {
135   char a[4] = {0};
136   memcpy(a, 0, 0); // no-warning
137 }
138 
memcpy_unknown_size(size_t n)139 void memcpy_unknown_size (size_t n) {
140   char a[4], b[4] = {1};
141   if (memcpy(a, b, n) != a)
142     (void)*(char*)0; // no-warning
143 }
144 
memcpy_unknown_size_warn(size_t n)145 void memcpy_unknown_size_warn (size_t n) {
146   char a[4];
147   if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
148     (void)*(char*)0; // no-warning
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   if (mempcpy(dst, src, 4) != &dst[4]) {
178     (void)*(char*)0; // no-warning
179   }
180 
181   if (dst[0] != 0)
182     (void)*(char*)0; // expected-warning{{null}}
183 }
184 
mempcpy1()185 void mempcpy1 () {
186   char src[] = {1, 2, 3, 4};
187   char dst[10];
188 
189   mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
190 }
191 
mempcpy2()192 void mempcpy2 () {
193   char src[] = {1, 2, 3, 4};
194   char dst[1];
195 
196   mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
197 }
198 
mempcpy3()199 void mempcpy3 () {
200   char src[] = {1, 2, 3, 4};
201   char dst[3];
202 
203   mempcpy(dst+1, src+2, 2); // no-warning
204 }
205 
mempcpy4()206 void mempcpy4 () {
207   char src[] = {1, 2, 3, 4};
208   char dst[10];
209 
210   mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
211 }
212 
mempcpy5()213 void mempcpy5() {
214   char src[] = {1, 2, 3, 4};
215   char dst[3];
216 
217   mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
218 }
219 
mempcpy6()220 void mempcpy6() {
221   int a[4] = {0};
222   mempcpy(a, a, 8); // expected-warning{{overlapping}}
223 }
224 
mempcpy7()225 void mempcpy7() {
226   int a[4] = {0};
227   mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
228 }
229 
mempcpy8()230 void mempcpy8() {
231   int a[4] = {0};
232   mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
233 }
234 
mempcpy9()235 void mempcpy9() {
236   int a[4] = {0};
237   mempcpy(a+2, a+1, 4); // no-warning
238   mempcpy(a+1, a+2, 4); // no-warning
239 }
240 
mempcpy10()241 void mempcpy10() {
242   char a[4] = {0};
243   mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
244 }
245 
mempcpy11()246 void mempcpy11() {
247   char a[4] = {0};
248   mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
249 }
250 
mempcpy12()251 void mempcpy12() {
252   char a[4] = {0};
253   mempcpy(0, a, 0); // no-warning
254 }
255 
mempcpy13()256 void mempcpy13() {
257   char a[4] = {0};
258   mempcpy(a, 0, 0); // no-warning
259 }
260 
mempcpy_unknown_size_warn(size_t n)261 void mempcpy_unknown_size_warn (size_t n) {
262   char a[4];
263   if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
264     (void)*(char*)0; // no-warning
265 }
266 
mempcpy_unknownable_size(char * src,float n)267 void mempcpy_unknownable_size (char *src, float n) {
268   char a[4];
269   // This used to crash because we don't model floats.
270   mempcpy(a, src, (size_t)n);
271 }
272 
273 //===----------------------------------------------------------------------===
274 // memmove()
275 //===----------------------------------------------------------------------===
276 
277 #ifdef VARIANT
278 
279 #define __memmove_chk BUILTIN(__memmove_chk)
280 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
281 
282 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
283 
284 #else /* VARIANT */
285 
286 #define memmove BUILTIN(memmove)
287 void *memmove(void *s1, const void *s2, size_t n);
288 
289 #endif /* VARIANT */
290 
291 
memmove0()292 void memmove0 () {
293   char src[] = {1, 2, 3, 4};
294   char dst[4] = {0};
295 
296   memmove(dst, src, 4); // no-warning
297 
298   if (memmove(dst, src, 4) != dst) {
299     (void)*(char*)0; // no-warning
300   }
301 
302   if (dst[0] != 0)
303     (void)*(char*)0; // expected-warning{{null}}
304 }
305 
memmove1()306 void memmove1 () {
307   char src[] = {1, 2, 3, 4};
308   char dst[10];
309 
310   memmove(dst, src, 5); // expected-warning{{out-of-bound}}
311 }
312 
memmove2()313 void memmove2 () {
314   char src[] = {1, 2, 3, 4};
315   char dst[1];
316 
317   memmove(dst, src, 4); // expected-warning{{overflow}}
318 }
319 
320 //===----------------------------------------------------------------------===
321 // memcmp()
322 //===----------------------------------------------------------------------===
323 
324 #ifdef VARIANT
325 
326 #define bcmp BUILTIN(bcmp)
327 // __builtin_bcmp is not defined with const in Builtins.def.
328 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
329 #define memcmp bcmp
330 
331 #else /* VARIANT */
332 
333 #define memcmp BUILTIN(memcmp)
334 int memcmp(const void *s1, const void *s2, size_t n);
335 
336 #endif /* VARIANT */
337 
338 
memcmp0()339 void memcmp0 () {
340   char a[] = {1, 2, 3, 4};
341   char b[4] = { 0 };
342 
343   memcmp(a, b, 4); // no-warning
344 }
345 
memcmp1()346 void memcmp1 () {
347   char a[] = {1, 2, 3, 4};
348   char b[10] = { 0 };
349 
350   memcmp(a, b, 5); // expected-warning{{out-of-bound}}
351 }
352 
memcmp2()353 void memcmp2 () {
354   char a[] = {1, 2, 3, 4};
355   char b[1] = { 0 };
356 
357   memcmp(a, b, 4); // expected-warning{{out-of-bound}}
358 }
359 
memcmp3()360 void memcmp3 () {
361   char a[] = {1, 2, 3, 4};
362 
363   if (memcmp(a, a, 4))
364     (void)*(char*)0; // no-warning
365 }
366 
memcmp4(char * input)367 void memcmp4 (char *input) {
368   char a[] = {1, 2, 3, 4};
369 
370   if (memcmp(a, input, 4))
371     (void)*(char*)0; // expected-warning{{null}}
372 }
373 
memcmp5(char * input)374 void memcmp5 (char *input) {
375   char a[] = {1, 2, 3, 4};
376 
377   if (memcmp(a, 0, 0)) // no-warning
378     (void)*(char*)0;   // no-warning
379   if (memcmp(0, a, 0)) // no-warning
380     (void)*(char*)0;   // no-warning
381   if (memcmp(a, input, 0)) // no-warning
382     (void)*(char*)0;   // no-warning
383 }
384 
memcmp6(char * a,char * b,size_t n)385 void memcmp6 (char *a, char *b, size_t n) {
386   int result = memcmp(a, b, n);
387   if (result != 0)
388     return;
389   if (n == 0)
390     (void)*(char*)0; // expected-warning{{null}}
391 }
392 
memcmp7(char * a,size_t x,size_t y,size_t n)393 int memcmp7 (char *a, size_t x, size_t y, size_t n) {
394   // We used to crash when either of the arguments was unknown.
395   return memcmp(a, &a[x*y], n) +
396          memcmp(&a[x*y], a, n);
397 }
398 
399 //===----------------------------------------------------------------------===
400 // bcopy()
401 //===----------------------------------------------------------------------===
402 
403 #define bcopy BUILTIN(bcopy)
404 // __builtin_bcopy is not defined with const in Builtins.def.
405 void bcopy(/*const*/ void *s1, void *s2, size_t n);
406 
407 
bcopy0()408 void bcopy0 () {
409   char src[] = {1, 2, 3, 4};
410   char dst[4] = {0};
411 
412   bcopy(src, dst, 4); // no-warning
413 
414   if (dst[0] != 0)
415     (void)*(char*)0; // expected-warning{{null}}
416 }
417 
bcopy1()418 void bcopy1 () {
419   char src[] = {1, 2, 3, 4};
420   char dst[10];
421 
422   bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
423 }
424 
bcopy2()425 void bcopy2 () {
426   char src[] = {1, 2, 3, 4};
427   char dst[1];
428 
429   bcopy(src, dst, 4); // expected-warning{{overflow}}
430 }
431