bstring.c revision be460d8e5364c6bffeb7b27e4c0d4d5d16e39c59
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,cplusplus.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
27typedef typeof(sizeof(int)) size_t;
28
29//===----------------------------------------------------------------------===
30// memcpy()
31//===----------------------------------------------------------------------===
32
33#ifdef VARIANT
34
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
41#else /* VARIANT */
42
43#define memcpy BUILTIN(memcpy)
44void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
45
46#endif /* VARIANT */
47
48
49void 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
63void memcpy1 () {
64  char src[] = {1, 2, 3, 4};
65  char dst[10];
66
67  memcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}}
68}
69
70void memcpy2 () {
71  char src[] = {1, 2, 3, 4};
72  char dst[1];
73
74  memcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}}
75}
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
88  memcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}}
89}
90
91void memcpy5() {
92  char src[] = {1, 2, 3, 4};
93  char dst[3];
94
95  memcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}}
96}
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
119void 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}
133
134void memcpy13() {
135  char a[4] = {0};
136  memcpy(a, 0, 0); // no-warning
137}
138
139//===----------------------------------------------------------------------===
140// mempcpy()
141//===----------------------------------------------------------------------===
142
143#ifdef VARIANT
144
145#define __mempcpy_chk BUILTIN(__mempcpy_chk)
146void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
147                   size_t destlen);
148
149#define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
150
151#else /* VARIANT */
152
153#define mempcpy BUILTIN(mempcpy)
154void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
155
156#endif /* VARIANT */
157
158
159void mempcpy0 () {
160  char src[] = {1, 2, 3, 4};
161  char dst[5] = {0};
162
163  mempcpy(dst, src, 4); // no-warning
164
165  if (mempcpy(dst, src, 4) != &dst[4]) {
166    (void)*(char*)0; // no-warning
167  }
168
169  if (dst[0] != 0)
170    (void)*(char*)0; // expected-warning{{null}}
171}
172
173void mempcpy1 () {
174  char src[] = {1, 2, 3, 4};
175  char dst[10];
176
177  mempcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}}
178}
179
180void mempcpy2 () {
181  char src[] = {1, 2, 3, 4};
182  char dst[1];
183
184  mempcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}}
185}
186
187void mempcpy3 () {
188  char src[] = {1, 2, 3, 4};
189  char dst[3];
190
191  mempcpy(dst+1, src+2, 2); // no-warning
192}
193
194void mempcpy4 () {
195  char src[] = {1, 2, 3, 4};
196  char dst[10];
197
198  mempcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}}
199}
200
201void mempcpy5() {
202  char src[] = {1, 2, 3, 4};
203  char dst[3];
204
205  mempcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}}
206}
207
208void mempcpy6() {
209  int a[4] = {0};
210  mempcpy(a, a, 8); // expected-warning{{overlapping}}
211}
212
213void mempcpy7() {
214  int a[4] = {0};
215  mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
216}
217
218void mempcpy8() {
219  int a[4] = {0};
220  mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
221}
222
223void mempcpy9() {
224  int a[4] = {0};
225  mempcpy(a+2, a+1, 4); // no-warning
226  mempcpy(a+1, a+2, 4); // no-warning
227}
228
229void mempcpy10() {
230  char a[4] = {0};
231  mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}}
232}
233
234void mempcpy11() {
235  char a[4] = {0};
236  mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}}
237}
238
239void mempcpy12() {
240  char a[4] = {0};
241  mempcpy(0, a, 0); // no-warning
242}
243
244void mempcpy13() {
245  char a[4] = {0};
246  mempcpy(a, 0, 0); // no-warning
247}
248
249//===----------------------------------------------------------------------===
250// memmove()
251//===----------------------------------------------------------------------===
252
253#ifdef VARIANT
254
255#define __memmove_chk BUILTIN(__memmove_chk)
256void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
257
258#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
259
260#else /* VARIANT */
261
262#define memmove BUILTIN(memmove)
263void *memmove(void *s1, const void *s2, size_t n);
264
265#endif /* VARIANT */
266
267
268void memmove0 () {
269  char src[] = {1, 2, 3, 4};
270  char dst[4] = {0};
271
272  memmove(dst, src, 4); // no-warning
273
274  if (memmove(dst, src, 4) != dst) {
275    (void)*(char*)0; // no-warning
276  }
277
278  if (dst[0] != 0)
279    (void)*(char*)0; // expected-warning{{null}}
280}
281
282void memmove1 () {
283  char src[] = {1, 2, 3, 4};
284  char dst[10];
285
286  memmove(dst, src, 5); // expected-warning{{out-of-bound}}
287}
288
289void memmove2 () {
290  char src[] = {1, 2, 3, 4};
291  char dst[1];
292
293  memmove(dst, src, 4); // expected-warning{{overflow}}
294}
295
296//===----------------------------------------------------------------------===
297// memcmp()
298//===----------------------------------------------------------------------===
299
300#ifdef VARIANT
301
302#define bcmp BUILTIN(bcmp)
303// __builtin_bcmp is not defined with const in Builtins.def.
304int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
305#define memcmp bcmp
306
307#else /* VARIANT */
308
309#define memcmp BUILTIN(memcmp)
310int memcmp(const void *s1, const void *s2, size_t n);
311
312#endif /* VARIANT */
313
314
315void memcmp0 () {
316  char a[] = {1, 2, 3, 4};
317  char b[4] = { 0 };
318
319  memcmp(a, b, 4); // no-warning
320}
321
322void memcmp1 () {
323  char a[] = {1, 2, 3, 4};
324  char b[10] = { 0 };
325
326  memcmp(a, b, 5); // expected-warning{{out-of-bound}}
327}
328
329void memcmp2 () {
330  char a[] = {1, 2, 3, 4};
331  char b[1] = { 0 };
332
333  memcmp(a, b, 4); // expected-warning{{out-of-bound}}
334}
335
336void memcmp3 () {
337  char a[] = {1, 2, 3, 4};
338
339  if (memcmp(a, a, 4))
340    (void)*(char*)0; // no-warning
341}
342
343void memcmp4 (char *input) {
344  char a[] = {1, 2, 3, 4};
345
346  if (memcmp(a, input, 4))
347    (void)*(char*)0; // expected-warning{{null}}
348}
349
350void memcmp5 (char *input) {
351  char a[] = {1, 2, 3, 4};
352
353  if (memcmp(a, 0, 0)) // no-warning
354    (void)*(char*)0;   // no-warning
355  if (memcmp(0, a, 0)) // no-warning
356    (void)*(char*)0;   // no-warning
357  if (memcmp(a, input, 0)) // no-warning
358    (void)*(char*)0;   // no-warning
359}
360
361void memcmp6 (char *a, char *b, size_t n) {
362  int result = memcmp(a, b, n);
363  if (result != 0)
364    return;
365  if (n == 0)
366    (void)*(char*)0; // expected-warning{{null}}
367}
368
369int memcmp7 (char *a, size_t x, size_t y, size_t n) {
370  // We used to crash when either of the arguments was unknown.
371  return memcmp(a, &a[x*y], n) +
372         memcmp(&a[x*y], a, n);
373}
374
375//===----------------------------------------------------------------------===
376// bcopy()
377//===----------------------------------------------------------------------===
378
379#define bcopy BUILTIN(bcopy)
380// __builtin_bcopy is not defined with const in Builtins.def.
381void bcopy(/*const*/ void *s1, void *s2, size_t n);
382
383
384void bcopy0 () {
385  char src[] = {1, 2, 3, 4};
386  char dst[4] = {0};
387
388  bcopy(src, dst, 4); // no-warning
389
390  if (dst[0] != 0)
391    (void)*(char*)0; // expected-warning{{null}}
392}
393
394void bcopy1 () {
395  char src[] = {1, 2, 3, 4};
396  char dst[10];
397
398  bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
399}
400
401void bcopy2 () {
402  char src[] = {1, 2, 3, 4};
403  char dst[1];
404
405  bcopy(src, dst, 4); // expected-warning{{overflow}}
406}
407