blob: 824aa7c063b78dd52f065a8efed8a3ddaa74164b [file] [log] [blame]
Ted Kremenek722398f2012-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 Rose134a2362010-07-06 23:11:01 +00005
6//===----------------------------------------------------------------------===
7// Declarations
8//===----------------------------------------------------------------------===
9
Jordy Rose33c829a2010-07-07 07:48:06 +000010// Some functions are so similar to each other that they follow the same code
Jordy Rose65136fb2010-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 Rose134a2362010-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 Lattner57540c52011-04-15 05:22:18 +000018// Functions that have variants and are also available as builtins should be
Jordy Rose33c829a2010-07-07 07:48:06 +000019// declared carefully! See memcpy() for an example.
Jordy Rose134a2362010-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 Rose6d5a8ca2012-05-16 16:01:10 +000029void clang_analyzer_eval(int);
30
Jordy Rose134a2362010-07-06 23:11:01 +000031//===----------------------------------------------------------------------===
32// memcpy()
33//===----------------------------------------------------------------------===
34
Jordy Rose33c829a2010-07-07 07:48:06 +000035#ifdef VARIANT
Jordy Rose134a2362010-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 Rose33c829a2010-07-07 07:48:06 +000043#else /* VARIANT */
Jordy Rose134a2362010-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 Rose33c829a2010-07-07 07:48:06 +000048#endif /* VARIANT */
Jordy Rose134a2362010-07-06 23:11:01 +000049
50
51void memcpy0 () {
52 char src[] = {1, 2, 3, 4};
Jordy Rose722f5582010-08-16 07:51:42 +000053 char dst[4] = {0};
Jordy Rose134a2362010-07-06 23:11:01 +000054
55 memcpy(dst, src, 4); // no-warning
56
Jordy Rose6d5a8ca2012-05-16 16:01:10 +000057 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
Jordy Rose722f5582010-08-16 07:51:42 +000058
Jordy Rose6d5a8ca2012-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 Rose134a2362010-07-06 23:11:01 +000062}
63
64void memcpy1 () {
65 char src[] = {1, 2, 3, 4};
66 char dst[10];
67
Jordy Rosedceb0cf2011-06-20 02:06:40 +000068 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Jordy Rose134a2362010-07-06 23:11:01 +000069}
70
71void memcpy2 () {
72 char src[] = {1, 2, 3, 4};
73 char dst[1];
74
Jordy Rosedceb0cf2011-06-20 02:06:40 +000075 memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
Jordy Rose134a2362010-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 Rosedceb0cf2011-06-20 02:06:40 +000089 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Jordy Rose134a2362010-07-06 23:11:01 +000090}
91
92void memcpy5() {
93 char src[] = {1, 2, 3, 4};
94 char dst[3];
95
Jordy Rosedceb0cf2011-06-20 02:06:40 +000096 memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
Jordy Rose134a2362010-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 Rose33c829a2010-07-07 07:48:06 +0000120void memcpy10() {
121 char a[4] = {0};
Jordy Rosedceb0cf2011-06-20 02:06:40 +0000122 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Jordy Rose33c829a2010-07-07 07:48:06 +0000123}
124
125void memcpy11() {
126 char a[4] = {0};
Jordy Rosedceb0cf2011-06-20 02:06:40 +0000127 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Jordy Rose33c829a2010-07-07 07:48:06 +0000128}
129
130void memcpy12() {
131 char a[4] = {0};
132 memcpy(0, a, 0); // no-warning
Lenny Maiorani79d74142011-03-31 21:36:53 +0000133}
134
135void memcpy13() {
136 char a[4] = {0};
Jordy Rose33c829a2010-07-07 07:48:06 +0000137 memcpy(a, 0, 0); // no-warning
138}
139
Jordy Rose63b84be2011-06-04 00:04:22 +0000140void memcpy_unknown_size (size_t n) {
141 char a[4], b[4] = {1};
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000142 clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
Jordy Rose63b84be2011-06-04 00:04:22 +0000143}
144
145void memcpy_unknown_size_warn (size_t n) {
146 char a[4];
Jordy Rose6d5a8ca2012-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 Rose63b84be2011-06-04 00:04:22 +0000149}
150
Jordy Rose134a2362010-07-06 23:11:01 +0000151//===----------------------------------------------------------------------===
Lenny Maiorani79d74142011-03-31 21:36:53 +0000152// mempcpy()
153//===----------------------------------------------------------------------===
154
Jordy Roseaee7fb92011-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 Maiorani79d74142011-03-31 21:36:53 +0000165#define mempcpy BUILTIN(mempcpy)
166void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
167
Jordy Roseaee7fb92011-06-03 23:42:56 +0000168#endif /* VARIANT */
169
170
Lenny Maiorani79d74142011-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 Rose6d5a8ca2012-05-16 16:01:10 +0000177 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
Lenny Maiorani79d74142011-03-31 21:36:53 +0000178
Jordy Rose6d5a8ca2012-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 Maiorani79d74142011-03-31 21:36:53 +0000182}
183
184void mempcpy1 () {
185 char src[] = {1, 2, 3, 4};
186 char dst[10];
187
Jordy Rosedceb0cf2011-06-20 02:06:40 +0000188 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Lenny Maiorani79d74142011-03-31 21:36:53 +0000189}
190
191void mempcpy2 () {
192 char src[] = {1, 2, 3, 4};
193 char dst[1];
194
Jordy Rosedceb0cf2011-06-20 02:06:40 +0000195 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
Lenny Maiorani79d74142011-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 Rosedceb0cf2011-06-20 02:06:40 +0000209 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
Lenny Maiorani79d74142011-03-31 21:36:53 +0000210}
211
212void mempcpy5() {
213 char src[] = {1, 2, 3, 4};
214 char dst[3];
215
Jordy Rosedceb0cf2011-06-20 02:06:40 +0000216 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
Lenny Maiorani79d74142011-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 Rosedceb0cf2011-06-20 02:06:40 +0000242 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Lenny Maiorani79d74142011-03-31 21:36:53 +0000243}
244
245void mempcpy11() {
246 char a[4] = {0};
Jordy Rosedceb0cf2011-06-20 02:06:40 +0000247 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
Lenny Maiorani79d74142011-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
Anna Zaks2d2f1372014-10-03 21:48:54 +0000260void 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
270struct st {
271 int i;
272 int j;
273};
274
275void 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
287void 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
Jordy Rose63b84be2011-06-04 00:04:22 +0000299void mempcpy_unknown_size_warn (size_t n) {
300 char a[4];
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000301 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)
Jordy Rose63b84be2011-06-04 00:04:22 +0000303}
304
Jordy Rose097c5392011-06-04 01:47:27 +0000305void 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
Lenny Maiorani79d74142011-03-31 21:36:53 +0000311//===----------------------------------------------------------------------===
Jordy Rose134a2362010-07-06 23:11:01 +0000312// memmove()
313//===----------------------------------------------------------------------===
314
Jordy Rose33c829a2010-07-07 07:48:06 +0000315#ifdef VARIANT
Jordy Rose134a2362010-07-06 23:11:01 +0000316
317#define __memmove_chk BUILTIN(__memmove_chk)
318void *__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
Jordy Rose33c829a2010-07-07 07:48:06 +0000322#else /* VARIANT */
Jordy Rose134a2362010-07-06 23:11:01 +0000323
324#define memmove BUILTIN(memmove)
325void *memmove(void *s1, const void *s2, size_t n);
326
Jordy Rose33c829a2010-07-07 07:48:06 +0000327#endif /* VARIANT */
Jordy Rose134a2362010-07-06 23:11:01 +0000328
329
330void memmove0 () {
331 char src[] = {1, 2, 3, 4};
Jordy Rose722f5582010-08-16 07:51:42 +0000332 char dst[4] = {0};
Jordy Rose134a2362010-07-06 23:11:01 +0000333
334 memmove(dst, src, 4); // no-warning
335
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000336 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
Jordy Rose722f5582010-08-16 07:51:42 +0000337
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000338 // 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}}
Jordy Rose134a2362010-07-06 23:11:01 +0000341}
342
343void 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
350void memmove2 () {
351 char src[] = {1, 2, 3, 4};
352 char dst[1];
353
Jordy Rose722f5582010-08-16 07:51:42 +0000354 memmove(dst, src, 4); // expected-warning{{overflow}}
Jordy Rose134a2362010-07-06 23:11:01 +0000355}
356
357//===----------------------------------------------------------------------===
Jordy Rose65136fb2010-07-07 08:15:01 +0000358// memcmp()
359//===----------------------------------------------------------------------===
360
361#ifdef VARIANT
362
363#define bcmp BUILTIN(bcmp)
364// __builtin_bcmp is not defined with const in Builtins.def.
365int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
366#define memcmp bcmp
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000367//
Jordy Rose65136fb2010-07-07 08:15:01 +0000368#else /* VARIANT */
369
370#define memcmp BUILTIN(memcmp)
371int memcmp(const void *s1, const void *s2, size_t n);
372
373#endif /* VARIANT */
374
375
376void memcmp0 () {
377 char a[] = {1, 2, 3, 4};
378 char b[4] = { 0 };
379
380 memcmp(a, b, 4); // no-warning
381}
382
383void 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
390void 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
397void memcmp3 () {
398 char a[] = {1, 2, 3, 4};
399
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000400 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
Jordy Rose65136fb2010-07-07 08:15:01 +0000401}
402
403void memcmp4 (char *input) {
404 char a[] = {1, 2, 3, 4};
405
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000406 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
Jordy Rose65136fb2010-07-07 08:15:01 +0000407}
408
409void memcmp5 (char *input) {
410 char a[] = {1, 2, 3, 4};
411
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000412 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}}
Jordy Rose65136fb2010-07-07 08:15:01 +0000415}
416
Jordy Rosed5d2e502010-07-08 23:57:29 +0000417void memcmp6 (char *a, char *b, size_t n) {
418 int result = memcmp(a, b, n);
419 if (result != 0)
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000420 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.
Jordy Rosed5d2e502010-07-08 23:57:29 +0000426}
427
Jordy Roseafdb0532010-08-05 23:11:30 +0000428int 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
Jordy Rose65136fb2010-07-07 08:15:01 +0000434//===----------------------------------------------------------------------===
Jordy Rose134a2362010-07-06 23:11:01 +0000435// bcopy()
436//===----------------------------------------------------------------------===
437
438#define bcopy BUILTIN(bcopy)
439// __builtin_bcopy is not defined with const in Builtins.def.
440void bcopy(/*const*/ void *s1, void *s2, size_t n);
441
442
443void bcopy0 () {
444 char src[] = {1, 2, 3, 4};
Jordy Rose722f5582010-08-16 07:51:42 +0000445 char dst[4] = {0};
Jordy Rose134a2362010-07-06 23:11:01 +0000446
447 bcopy(src, dst, 4); // no-warning
Jordy Rose722f5582010-08-16 07:51:42 +0000448
Jordy Rose6d5a8ca2012-05-16 16:01:10 +0000449 // 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}}
Jordy Rose134a2362010-07-06 23:11:01 +0000452}
453
454void 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
461void bcopy2 () {
462 char src[] = {1, 2, 3, 4};
463 char dst[1];
464
Jordy Rose722f5582010-08-16 07:51:42 +0000465 bcopy(src, dst, 4); // expected-warning{{overflow}}
Jordy Rose134a2362010-07-06 23:11:01 +0000466}
Anna Zaksb3b56bb2012-05-03 18:21:28 +0000467
468void *malloc(size_t);
469void free(void *);
470char 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}