blob: 69d281afee4a14baedf41ae04f3566c34f046b92 [file] [log] [blame]
Ted Kremenekcdc3a892012-08-24 20:39:55 +00001// 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
Jordy Roseccbf7ee2010-07-06 23:11:01 +00005
6//===----------------------------------------------------------------------===
7// Declarations
8//===----------------------------------------------------------------------===
9
Jordy Rosea6b808c2010-07-07 07:48:06 +000010// Some functions are so similar to each other that they follow the same code
Jordy Rosebc56d1f2010-07-07 08:15:01 +000011// 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.
Jordy Roseccbf7ee2010-07-06 23:11:01 +000014
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
Chris Lattnerfc8f0e12011-04-15 05:22:18 +000018// Functions that have variants and are also available as builtins should be
Jordy Rosea6b808c2010-07-07 07:48:06 +000019// declared carefully! See memcpy() for an example.
Jordy Roseccbf7ee2010-07-06 23:11:01 +000020
21#ifdef USE_BUILTINS
22# define BUILTIN(f) __builtin_ ## f
23#else /* USE_BUILTINS */
24# define BUILTIN(f) f
25#endif /* USE_BUILTINS */
26
27typedef typeof(sizeof(int)) size_t;
28
Jordy Rose43d9f0d2012-05-16 16:01:10 +000029void clang_analyzer_eval(int);
30
Jordy Roseccbf7ee2010-07-06 23:11:01 +000031//===----------------------------------------------------------------------===
32// memcpy()
33//===----------------------------------------------------------------------===
34
Jordy Rosea6b808c2010-07-07 07:48:06 +000035#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +000036
37#define __memcpy_chk BUILTIN(__memcpy_chk)
38void *__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
Jordy Rosea6b808c2010-07-07 07:48:06 +000043#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +000044
45#define memcpy BUILTIN(memcpy)
46void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
47
Jordy Rosea6b808c2010-07-07 07:48:06 +000048#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +000049
50
51void memcpy0 () {
52 char src[] = {1, 2, 3, 4};
Jordy Rosee64f3112010-08-16 07:51:42 +000053 char dst[4] = {0};
Jordy Roseccbf7ee2010-07-06 23:11:01 +000054
55 memcpy(dst, src, 4); // no-warning
56
Jordy Rose43d9f0d2012-05-16 16:01:10 +000057 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
Jordy Rosee64f3112010-08-16 07:51:42 +000058
Jordy Rose43d9f0d2012-05-16 16:01:10 +000059 // 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}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000062}
63
64void memcpy1 () {
65 char src[] = {1, 2, 3, 4};
66 char dst[10];
67
Jordy Rose9e49d9f2011-06-20 02:06:40 +000068 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000069}
70
71void memcpy2 () {
72 char src[] = {1, 2, 3, 4};
73 char dst[1];
74
Jordy Rose9e49d9f2011-06-20 02:06:40 +000075 memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000076}
77
78void memcpy3 () {
79 char src[] = {1, 2, 3, 4};
80 char dst[3];
81
82 memcpy(dst+1, src+2, 2); // no-warning
83}
84
85void memcpy4 () {
86 char src[] = {1, 2, 3, 4};
87 char dst[10];
88
Jordy Rose9e49d9f2011-06-20 02:06:40 +000089 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000090}
91
92void memcpy5() {
93 char src[] = {1, 2, 3, 4};
94 char dst[3];
95
Jordy Rose9e49d9f2011-06-20 02:06:40 +000096 memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000097}
98
99void memcpy6() {
100 int a[4] = {0};
101 memcpy(a, a, 8); // expected-warning{{overlapping}}
102}
103
104void memcpy7() {
105 int a[4] = {0};
106 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
107}
108
109void memcpy8() {
110 int a[4] = {0};
111 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
112}
113
114void 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
Jordy Rosea6b808c2010-07-07 07:48:06 +0000120void memcpy10() {
121 char a[4] = {0};
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000122 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Jordy Rosea6b808c2010-07-07 07:48:06 +0000123}
124
125void memcpy11() {
126 char a[4] = {0};
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000127 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Jordy Rosea6b808c2010-07-07 07:48:06 +0000128}
129
130void memcpy12() {
131 char a[4] = {0};
132 memcpy(0, a, 0); // no-warning
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000133}
134
135void memcpy13() {
136 char a[4] = {0};
Jordy Rosea6b808c2010-07-07 07:48:06 +0000137 memcpy(a, 0, 0); // no-warning
138}
139
Jordy Rose22d27172011-06-04 00:04:22 +0000140void memcpy_unknown_size (size_t n) {
141 char a[4], b[4] = {1};
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000142 clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
Jordy Rose22d27172011-06-04 00:04:22 +0000143}
144
145void memcpy_unknown_size_warn (size_t n) {
146 char a[4];
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000147 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)
Jordy Rose22d27172011-06-04 00:04:22 +0000149}
150
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000151//===----------------------------------------------------------------------===
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000152// mempcpy()
153//===----------------------------------------------------------------------===
154
Jordy Rosebe460d82011-06-03 23:42:56 +0000155#ifdef VARIANT
156
157#define __mempcpy_chk BUILTIN(__mempcpy_chk)
158void *__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
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000165#define mempcpy BUILTIN(mempcpy)
166void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
167
Jordy Rosebe460d82011-06-03 23:42:56 +0000168#endif /* VARIANT */
169
170
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000171void mempcpy0 () {
172 char src[] = {1, 2, 3, 4};
173 char dst[5] = {0};
174
175 mempcpy(dst, src, 4); // no-warning
176
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000177 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000178
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000179 // 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}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000182}
183
184void mempcpy1 () {
185 char src[] = {1, 2, 3, 4};
186 char dst[10];
187
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000188 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000189}
190
191void mempcpy2 () {
192 char src[] = {1, 2, 3, 4};
193 char dst[1];
194
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000195 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000196}
197
198void mempcpy3 () {
199 char src[] = {1, 2, 3, 4};
200 char dst[3];
201
202 mempcpy(dst+1, src+2, 2); // no-warning
203}
204
205void mempcpy4 () {
206 char src[] = {1, 2, 3, 4};
207 char dst[10];
208
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000209 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000210}
211
212void mempcpy5() {
213 char src[] = {1, 2, 3, 4};
214 char dst[3];
215
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000216 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000217}
218
219void mempcpy6() {
220 int a[4] = {0};
221 mempcpy(a, a, 8); // expected-warning{{overlapping}}
222}
223
224void mempcpy7() {
225 int a[4] = {0};
226 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
227}
228
229void mempcpy8() {
230 int a[4] = {0};
231 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
232}
233
234void 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
240void mempcpy10() {
241 char a[4] = {0};
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000242 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000243}
244
245void mempcpy11() {
246 char a[4] = {0};
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000247 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000248}
249
250void mempcpy12() {
251 char a[4] = {0};
252 mempcpy(0, a, 0); // no-warning
253}
254
255void mempcpy13() {
256 char a[4] = {0};
257 mempcpy(a, 0, 0); // no-warning
258}
259
Jordy Rose22d27172011-06-04 00:04:22 +0000260void mempcpy_unknown_size_warn (size_t n) {
261 char a[4];
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000262 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
263 clang_analyzer_eval(result == a); // no-warning (above is fatal)
Jordy Rose22d27172011-06-04 00:04:22 +0000264}
265
Jordy Rose3f8bb2f2011-06-04 01:47:27 +0000266void mempcpy_unknownable_size (char *src, float n) {
267 char a[4];
268 // This used to crash because we don't model floats.
269 mempcpy(a, src, (size_t)n);
270}
271
Lenny Maioranib8b875b2011-03-31 21:36:53 +0000272//===----------------------------------------------------------------------===
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000273// memmove()
274//===----------------------------------------------------------------------===
275
Jordy Rosea6b808c2010-07-07 07:48:06 +0000276#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000277
278#define __memmove_chk BUILTIN(__memmove_chk)
279void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
280
281#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
282
Jordy Rosea6b808c2010-07-07 07:48:06 +0000283#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000284
285#define memmove BUILTIN(memmove)
286void *memmove(void *s1, const void *s2, size_t n);
287
Jordy Rosea6b808c2010-07-07 07:48:06 +0000288#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000289
290
291void memmove0 () {
292 char src[] = {1, 2, 3, 4};
Jordy Rosee64f3112010-08-16 07:51:42 +0000293 char dst[4] = {0};
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000294
295 memmove(dst, src, 4); // no-warning
296
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000297 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000298
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000299 // If we actually model the copy, we can make this known.
300 // The important thing for now is that the old value has been invalidated.
301 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000302}
303
304void memmove1 () {
305 char src[] = {1, 2, 3, 4};
306 char dst[10];
307
308 memmove(dst, src, 5); // expected-warning{{out-of-bound}}
309}
310
311void memmove2 () {
312 char src[] = {1, 2, 3, 4};
313 char dst[1];
314
Jordy Rosee64f3112010-08-16 07:51:42 +0000315 memmove(dst, src, 4); // expected-warning{{overflow}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000316}
317
318//===----------------------------------------------------------------------===
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000319// memcmp()
320//===----------------------------------------------------------------------===
321
322#ifdef VARIANT
323
324#define bcmp BUILTIN(bcmp)
325// __builtin_bcmp is not defined with const in Builtins.def.
326int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
327#define memcmp bcmp
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000328//
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000329#else /* VARIANT */
330
331#define memcmp BUILTIN(memcmp)
332int memcmp(const void *s1, const void *s2, size_t n);
333
334#endif /* VARIANT */
335
336
337void memcmp0 () {
338 char a[] = {1, 2, 3, 4};
339 char b[4] = { 0 };
340
341 memcmp(a, b, 4); // no-warning
342}
343
344void memcmp1 () {
345 char a[] = {1, 2, 3, 4};
346 char b[10] = { 0 };
347
348 memcmp(a, b, 5); // expected-warning{{out-of-bound}}
349}
350
351void memcmp2 () {
352 char a[] = {1, 2, 3, 4};
353 char b[1] = { 0 };
354
355 memcmp(a, b, 4); // expected-warning{{out-of-bound}}
356}
357
358void memcmp3 () {
359 char a[] = {1, 2, 3, 4};
360
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000361 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000362}
363
364void memcmp4 (char *input) {
365 char a[] = {1, 2, 3, 4};
366
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000367 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000368}
369
370void memcmp5 (char *input) {
371 char a[] = {1, 2, 3, 4};
372
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000373 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
374 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
375 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000376}
377
Jordy Rosed325ffb2010-07-08 23:57:29 +0000378void memcmp6 (char *a, char *b, size_t n) {
379 int result = memcmp(a, b, n);
380 if (result != 0)
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000381 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
382 // else
383 // analyzer_assert_unknown(n == 0);
384
385 // We can't do the above comparison because n has already been constrained.
386 // On one path n == 0, on the other n != 0.
Jordy Rosed325ffb2010-07-08 23:57:29 +0000387}
388
Jordy Roseb6a40262010-08-05 23:11:30 +0000389int memcmp7 (char *a, size_t x, size_t y, size_t n) {
390 // We used to crash when either of the arguments was unknown.
391 return memcmp(a, &a[x*y], n) +
392 memcmp(&a[x*y], a, n);
393}
394
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000395//===----------------------------------------------------------------------===
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000396// bcopy()
397//===----------------------------------------------------------------------===
398
399#define bcopy BUILTIN(bcopy)
400// __builtin_bcopy is not defined with const in Builtins.def.
401void bcopy(/*const*/ void *s1, void *s2, size_t n);
402
403
404void bcopy0 () {
405 char src[] = {1, 2, 3, 4};
Jordy Rosee64f3112010-08-16 07:51:42 +0000406 char dst[4] = {0};
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000407
408 bcopy(src, dst, 4); // no-warning
Jordy Rosee64f3112010-08-16 07:51:42 +0000409
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000410 // If we actually model the copy, we can make this known.
411 // The important thing for now is that the old value has been invalidated.
412 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000413}
414
415void bcopy1 () {
416 char src[] = {1, 2, 3, 4};
417 char dst[10];
418
419 bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
420}
421
422void bcopy2 () {
423 char src[] = {1, 2, 3, 4};
424 char dst[1];
425
Jordy Rosee64f3112010-08-16 07:51:42 +0000426 bcopy(src, dst, 4); // expected-warning{{overflow}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000427}
Anna Zaksdd160f32012-05-03 18:21:28 +0000428
429void *malloc(size_t);
430void free(void *);
431char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) {
432 char *bytes = malloc(sizeof(char) * (length + 1));
433 memcpy(bytes, input, length);
434 char x = bytes[0]; // no warning
435 free(bytes);
436 return x;
437}