blob: 59d6318db335d5e404c2da1b5f4bc46222012c28 [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};
51 char dst[4];
52
53 memcpy(dst, src, 4); // no-warning
54
55 if (memcpy(dst, src, 4) != dst) {
56 (void)*(char*)0; // no-warning -- should be unreachable
57 }
58}
59
60void memcpy1 () {
61 char src[] = {1, 2, 3, 4};
62 char dst[10];
63
64 memcpy(dst, src, 5); // expected-warning{{out-of-bound}}
65}
66
67void memcpy2 () {
68 char src[] = {1, 2, 3, 4};
69 char dst[1];
70
71 memcpy(dst, src, 4); // expected-warning{{out-of-bound}}
72}
73
74void memcpy3 () {
75 char src[] = {1, 2, 3, 4};
76 char dst[3];
77
78 memcpy(dst+1, src+2, 2); // no-warning
79}
80
81void memcpy4 () {
82 char src[] = {1, 2, 3, 4};
83 char dst[10];
84
85 memcpy(dst+2, src+2, 3); // expected-warning{{out-of-bound}}
86}
87
88void memcpy5() {
89 char src[] = {1, 2, 3, 4};
90 char dst[3];
91
92 memcpy(dst+2, src+2, 2); // expected-warning{{out-of-bound}}
93}
94
95void memcpy6() {
96 int a[4] = {0};
97 memcpy(a, a, 8); // expected-warning{{overlapping}}
98}
99
100void memcpy7() {
101 int a[4] = {0};
102 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
103}
104
105void memcpy8() {
106 int a[4] = {0};
107 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
108}
109
110void memcpy9() {
111 int a[4] = {0};
112 memcpy(a+2, a+1, 4); // no-warning
113 memcpy(a+1, a+2, 4); // no-warning
114}
115
Jordy Rosea6b808c2010-07-07 07:48:06 +0000116void memcpy10() {
117 char a[4] = {0};
118 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}}
119}
120
121void memcpy11() {
122 char a[4] = {0};
123 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}}
124}
125
126void memcpy12() {
127 char a[4] = {0};
128 memcpy(0, a, 0); // no-warning
129 memcpy(a, 0, 0); // no-warning
130}
131
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000132//===----------------------------------------------------------------------===
133// memmove()
134//===----------------------------------------------------------------------===
135
Jordy Rosea6b808c2010-07-07 07:48:06 +0000136#ifdef VARIANT
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000137
138#define __memmove_chk BUILTIN(__memmove_chk)
139void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
140
141#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
142
Jordy Rosea6b808c2010-07-07 07:48:06 +0000143#else /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000144
145#define memmove BUILTIN(memmove)
146void *memmove(void *s1, const void *s2, size_t n);
147
Jordy Rosea6b808c2010-07-07 07:48:06 +0000148#endif /* VARIANT */
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000149
150
151void memmove0 () {
152 char src[] = {1, 2, 3, 4};
153 char dst[4];
154
155 memmove(dst, src, 4); // no-warning
156
157 if (memmove(dst, src, 4) != dst) {
158 (void)*(char*)0; // no-warning -- should be unreachable
159 }
160}
161
162void memmove1 () {
163 char src[] = {1, 2, 3, 4};
164 char dst[10];
165
166 memmove(dst, src, 5); // expected-warning{{out-of-bound}}
167}
168
169void memmove2 () {
170 char src[] = {1, 2, 3, 4};
171 char dst[1];
172
173 memmove(dst, src, 4); // expected-warning{{out-of-bound}}
174}
175
176//===----------------------------------------------------------------------===
Jordy Rosebc56d1f2010-07-07 08:15:01 +0000177// memcmp()
178//===----------------------------------------------------------------------===
179
180#ifdef VARIANT
181
182#define bcmp BUILTIN(bcmp)
183// __builtin_bcmp is not defined with const in Builtins.def.
184int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
185#define memcmp bcmp
186
187#else /* VARIANT */
188
189#define memcmp BUILTIN(memcmp)
190int memcmp(const void *s1, const void *s2, size_t n);
191
192#endif /* VARIANT */
193
194
195void memcmp0 () {
196 char a[] = {1, 2, 3, 4};
197 char b[4] = { 0 };
198
199 memcmp(a, b, 4); // no-warning
200}
201
202void memcmp1 () {
203 char a[] = {1, 2, 3, 4};
204 char b[10] = { 0 };
205
206 memcmp(a, b, 5); // expected-warning{{out-of-bound}}
207}
208
209void memcmp2 () {
210 char a[] = {1, 2, 3, 4};
211 char b[1] = { 0 };
212
213 memcmp(a, b, 4); // expected-warning{{out-of-bound}}
214}
215
216void memcmp3 () {
217 char a[] = {1, 2, 3, 4};
218
219 if (memcmp(a, a, 4))
220 (void)*(char*)0; // no-warning
221}
222
223void memcmp4 (char *input) {
224 char a[] = {1, 2, 3, 4};
225
226 if (memcmp(a, input, 4))
227 (void)*(char*)0; // expected-warning{{null}}
228}
229
230void memcmp5 (char *input) {
231 char a[] = {1, 2, 3, 4};
232
233 if (memcmp(a, 0, 0)) // no-warning
234 (void)*(char*)0; // no-warning
235 if (memcmp(0, a, 0)) // no-warning
236 (void)*(char*)0; // no-warning
237 if (memcmp(a, input, 0)) // no-warning
238 (void)*(char*)0; // no-warning
239}
240
241//===----------------------------------------------------------------------===
Jordy Roseccbf7ee2010-07-06 23:11:01 +0000242// bcopy()
243//===----------------------------------------------------------------------===
244
245#define bcopy BUILTIN(bcopy)
246// __builtin_bcopy is not defined with const in Builtins.def.
247void bcopy(/*const*/ void *s1, void *s2, size_t n);
248
249
250void bcopy0 () {
251 char src[] = {1, 2, 3, 4};
252 char dst[4];
253
254 bcopy(src, dst, 4); // no-warning
255}
256
257void bcopy1 () {
258 char src[] = {1, 2, 3, 4};
259 char dst[10];
260
261 bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
262}
263
264void bcopy2 () {
265 char src[] = {1, 2, 3, 4};
266 char dst[1];
267
268 bcopy(src, dst, 4); // expected-warning{{out-of-bound}}
269}