blob: ffe420f725171e4dd02e1e28c85793459b4c6719 [file] [log] [blame]
Jordy Roseccbf7ee2010-07-06 23:11:01 +00001// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
Jordy Rosea6b808c2010-07-07 07:48:06 +00003// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -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
Jordy Rosea6b808c2010-07-07 07:48:06 +000018// Functions that have variants and are also availabe as builtins should be
19// 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
29//===----------------------------------------------------------------------===
30// memcpy()
31//===----------------------------------------------------------------------===
32
Jordy Rosea6b808c2010-07-07 07:48:06 +000033#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +000034
35#define __memcpy_chk BUILTIN(__memcpy_chk)
36void *__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
Jordy Rosea6b808c2010-07-07 07:48:06 +000041#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +000042
43#define memcpy BUILTIN(memcpy)
44void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
45
Jordy Rosea6b808c2010-07-07 07:48:06 +000046#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +000047
48
49void memcpy0 () {
50 char src[] = {1, 2, 3, 4};
Jordy Rosee64f3112010-08-16 07:51:42 +000051 char dst[4] = {0};
Jordy Roseccbf7ee2010-07-06 23:11:01 +000052
53 memcpy(dst, src, 4); // no-warning
54
55 if (memcpy(dst, src, 4) != dst) {
Tom Care7bce3a12010-07-27 23:30:21 +000056 (void)*(char*)0; // no-warning
Jordy Roseccbf7ee2010-07-06 23:11:01 +000057 }
Jordy Rosee64f3112010-08-16 07:51:42 +000058
59 if (dst[0] != 0)
60 (void)*(char*)0; // expected-warning{{null}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000061}
62
63void memcpy1 () {
64 char src[] = {1, 2, 3, 4};
65 char dst[10];
66
Jordy Rosee64f3112010-08-16 07:51:42 +000067 memcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000068}
69
70void memcpy2 () {
71 char src[] = {1, 2, 3, 4};
72 char dst[1];
73
Jordy Rosee64f3112010-08-16 07:51:42 +000074 memcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000075}
76
77void memcpy3 () {
78 char src[] = {1, 2, 3, 4};
79 char dst[3];
80
81 memcpy(dst+1, src+2, 2); // no-warning
82}
83
84void memcpy4 () {
85 char src[] = {1, 2, 3, 4};
86 char dst[10];
87
Jordy Rosee64f3112010-08-16 07:51:42 +000088 memcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000089}
90
91void memcpy5() {
92 char src[] = {1, 2, 3, 4};
93 char dst[3];
94
Jordy Rosee64f3112010-08-16 07:51:42 +000095 memcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +000096}
97
98void memcpy6() {
99 int a[4] = {0};
100 memcpy(a, a, 8); // expected-warning{{overlapping}}
101}
102
103void memcpy7() {
104 int a[4] = {0};
105 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
106}
107
108void memcpy8() {
109 int a[4] = {0};
110 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
111}
112
113void 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
Jordy Rosea6b808c2010-07-07 07:48:06 +0000119void memcpy10() {
120 char a[4] = {0};
121 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}}
122}
123
124void memcpy11() {
125 char a[4] = {0};
126 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}}
127}
128
129void memcpy12() {
130 char a[4] = {0};
131 memcpy(0, a, 0); // no-warning
132 memcpy(a, 0, 0); // no-warning
133}
134
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000135//===----------------------------------------------------------------------===
136// memmove()
137//===----------------------------------------------------------------------===
138
Jordy Rosea6b808c2010-07-07 07:48:06 +0000139#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000140
141#define __memmove_chk BUILTIN(__memmove_chk)
142void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
143
144#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
145
Jordy Rosea6b808c2010-07-07 07:48:06 +0000146#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000147
148#define memmove BUILTIN(memmove)
149void *memmove(void *s1, const void *s2, size_t n);
150
Jordy Rosea6b808c2010-07-07 07:48:06 +0000151#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000152
153
154void memmove0 () {
155 char src[] = {1, 2, 3, 4};
Jordy Rosee64f3112010-08-16 07:51:42 +0000156 char dst[4] = {0};
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000157
158 memmove(dst, src, 4); // no-warning
159
160 if (memmove(dst, src, 4) != dst) {
Tom Care7bce3a12010-07-27 23:30:21 +0000161 (void)*(char*)0; // no-warning
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000162 }
Jordy Rosee64f3112010-08-16 07:51:42 +0000163
164 if (dst[0] != 0)
165 (void)*(char*)0; // expected-warning{{null}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000166}
167
168void memmove1 () {
169 char src[] = {1, 2, 3, 4};
170 char dst[10];
171
172 memmove(dst, src, 5); // expected-warning{{out-of-bound}}
173}
174
175void memmove2 () {
176 char src[] = {1, 2, 3, 4};
177 char dst[1];
178
Jordy Rosee64f3112010-08-16 07:51:42 +0000179 memmove(dst, src, 4); // expected-warning{{overflow}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000180}
181
182//===----------------------------------------------------------------------===
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000183// memcmp()
184//===----------------------------------------------------------------------===
185
186#ifdef VARIANT
187
188#define bcmp BUILTIN(bcmp)
189// __builtin_bcmp is not defined with const in Builtins.def.
190int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
191#define memcmp bcmp
192
193#else /* VARIANT */
194
195#define memcmp BUILTIN(memcmp)
196int memcmp(const void *s1, const void *s2, size_t n);
197
198#endif /* VARIANT */
199
200
201void memcmp0 () {
202 char a[] = {1, 2, 3, 4};
203 char b[4] = { 0 };
204
205 memcmp(a, b, 4); // no-warning
206}
207
208void memcmp1 () {
209 char a[] = {1, 2, 3, 4};
210 char b[10] = { 0 };
211
212 memcmp(a, b, 5); // expected-warning{{out-of-bound}}
213}
214
215void memcmp2 () {
216 char a[] = {1, 2, 3, 4};
217 char b[1] = { 0 };
218
219 memcmp(a, b, 4); // expected-warning{{out-of-bound}}
220}
221
222void memcmp3 () {
223 char a[] = {1, 2, 3, 4};
224
225 if (memcmp(a, a, 4))
Tom Care7bce3a12010-07-27 23:30:21 +0000226 (void)*(char*)0; // no-warning
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000227}
228
229void memcmp4 (char *input) {
230 char a[] = {1, 2, 3, 4};
231
232 if (memcmp(a, input, 4))
233 (void)*(char*)0; // expected-warning{{null}}
234}
235
236void memcmp5 (char *input) {
237 char a[] = {1, 2, 3, 4};
238
239 if (memcmp(a, 0, 0)) // no-warning
Tom Care7bce3a12010-07-27 23:30:21 +0000240 (void)*(char*)0; // no-warning
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000241 if (memcmp(0, a, 0)) // no-warning
Tom Care7bce3a12010-07-27 23:30:21 +0000242 (void)*(char*)0; // no-warning
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000243 if (memcmp(a, input, 0)) // no-warning
Tom Care7bce3a12010-07-27 23:30:21 +0000244 (void)*(char*)0; // no-warning
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000245}
246
Jordy Rosed325ffb2010-07-08 23:57:29 +0000247void memcmp6 (char *a, char *b, size_t n) {
248 int result = memcmp(a, b, n);
249 if (result != 0)
250 return;
251 if (n == 0)
252 (void)*(char*)0; // expected-warning{{null}}
253}
254
Jordy Roseb6a40262010-08-05 23:11:30 +0000255int memcmp7 (char *a, size_t x, size_t y, size_t n) {
256 // We used to crash when either of the arguments was unknown.
257 return memcmp(a, &a[x*y], n) +
258 memcmp(&a[x*y], a, n);
259}
260
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000261//===----------------------------------------------------------------------===
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000262// bcopy()
263//===----------------------------------------------------------------------===
264
265#define bcopy BUILTIN(bcopy)
266// __builtin_bcopy is not defined with const in Builtins.def.
267void bcopy(/*const*/ void *s1, void *s2, size_t n);
268
269
270void bcopy0 () {
271 char src[] = {1, 2, 3, 4};
Jordy Rosee64f3112010-08-16 07:51:42 +0000272 char dst[4] = {0};
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000273
274 bcopy(src, dst, 4); // no-warning
Jordy Rosee64f3112010-08-16 07:51:42 +0000275
276 if (dst[0] != 0)
277 (void)*(char*)0; // expected-warning{{null}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000278}
279
280void bcopy1 () {
281 char src[] = {1, 2, 3, 4};
282 char dst[10];
283
284 bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
285}
286
287void bcopy2 () {
288 char src[] = {1, 2, 3, 4};
289 char dst[1];
290
Jordy Rosee64f3112010-08-16 07:51:42 +0000291 bcopy(src, dst, 4); // expected-warning{{overflow}}
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000292}