bstring.c revision 9e49d9fbdc861c25c2480233147dee07f5fa9660
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s
4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.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{{Memory copy 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{{Memory copy 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{{Memory copy 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{{Memory copy 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 memory copy function}}
122}
123
124void memcpy11() {
125  char a[4] = {0};
126  memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy 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
139void memcpy_unknown_size (size_t n) {
140  char a[4], b[4] = {1};
141  if (memcpy(a, b, n) != a)
142    (void)*(char*)0; // no-warning
143}
144
145void memcpy_unknown_size_warn (size_t n) {
146  char a[4];
147  if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
148    (void)*(char*)0; // no-warning
149}
150
151//===----------------------------------------------------------------------===
152// mempcpy()
153//===----------------------------------------------------------------------===
154
155#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
165#define mempcpy BUILTIN(mempcpy)
166void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
167
168#endif /* VARIANT */
169
170
171void mempcpy0 () {
172  char src[] = {1, 2, 3, 4};
173  char dst[5] = {0};
174
175  mempcpy(dst, src, 4); // no-warning
176
177  if (mempcpy(dst, src, 4) != &dst[4]) {
178    (void)*(char*)0; // no-warning
179  }
180
181  if (dst[0] != 0)
182    (void)*(char*)0; // expected-warning{{null}}
183}
184
185void mempcpy1 () {
186  char src[] = {1, 2, 3, 4};
187  char dst[10];
188
189  mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
190}
191
192void mempcpy2 () {
193  char src[] = {1, 2, 3, 4};
194  char dst[1];
195
196  mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
197}
198
199void mempcpy3 () {
200  char src[] = {1, 2, 3, 4};
201  char dst[3];
202
203  mempcpy(dst+1, src+2, 2); // no-warning
204}
205
206void mempcpy4 () {
207  char src[] = {1, 2, 3, 4};
208  char dst[10];
209
210  mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
211}
212
213void mempcpy5() {
214  char src[] = {1, 2, 3, 4};
215  char dst[3];
216
217  mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
218}
219
220void mempcpy6() {
221  int a[4] = {0};
222  mempcpy(a, a, 8); // expected-warning{{overlapping}}
223}
224
225void mempcpy7() {
226  int a[4] = {0};
227  mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
228}
229
230void mempcpy8() {
231  int a[4] = {0};
232  mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
233}
234
235void mempcpy9() {
236  int a[4] = {0};
237  mempcpy(a+2, a+1, 4); // no-warning
238  mempcpy(a+1, a+2, 4); // no-warning
239}
240
241void mempcpy10() {
242  char a[4] = {0};
243  mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
244}
245
246void mempcpy11() {
247  char a[4] = {0};
248  mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
249}
250
251void mempcpy12() {
252  char a[4] = {0};
253  mempcpy(0, a, 0); // no-warning
254}
255
256void mempcpy13() {
257  char a[4] = {0};
258  mempcpy(a, 0, 0); // no-warning
259}
260
261void mempcpy_unknown_size_warn (size_t n) {
262  char a[4];
263  if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
264    (void)*(char*)0; // no-warning
265}
266
267void mempcpy_unknownable_size (char *src, float n) {
268  char a[4];
269  // This used to crash because we don't model floats.
270  mempcpy(a, src, (size_t)n);
271}
272
273//===----------------------------------------------------------------------===
274// memmove()
275//===----------------------------------------------------------------------===
276
277#ifdef VARIANT
278
279#define __memmove_chk BUILTIN(__memmove_chk)
280void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
281
282#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
283
284#else /* VARIANT */
285
286#define memmove BUILTIN(memmove)
287void *memmove(void *s1, const void *s2, size_t n);
288
289#endif /* VARIANT */
290
291
292void memmove0 () {
293  char src[] = {1, 2, 3, 4};
294  char dst[4] = {0};
295
296  memmove(dst, src, 4); // no-warning
297
298  if (memmove(dst, src, 4) != dst) {
299    (void)*(char*)0; // no-warning
300  }
301
302  if (dst[0] != 0)
303    (void)*(char*)0; // expected-warning{{null}}
304}
305
306void memmove1 () {
307  char src[] = {1, 2, 3, 4};
308  char dst[10];
309
310  memmove(dst, src, 5); // expected-warning{{out-of-bound}}
311}
312
313void memmove2 () {
314  char src[] = {1, 2, 3, 4};
315  char dst[1];
316
317  memmove(dst, src, 4); // expected-warning{{overflow}}
318}
319
320//===----------------------------------------------------------------------===
321// memcmp()
322//===----------------------------------------------------------------------===
323
324#ifdef VARIANT
325
326#define bcmp BUILTIN(bcmp)
327// __builtin_bcmp is not defined with const in Builtins.def.
328int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
329#define memcmp bcmp
330
331#else /* VARIANT */
332
333#define memcmp BUILTIN(memcmp)
334int memcmp(const void *s1, const void *s2, size_t n);
335
336#endif /* VARIANT */
337
338
339void memcmp0 () {
340  char a[] = {1, 2, 3, 4};
341  char b[4] = { 0 };
342
343  memcmp(a, b, 4); // no-warning
344}
345
346void memcmp1 () {
347  char a[] = {1, 2, 3, 4};
348  char b[10] = { 0 };
349
350  memcmp(a, b, 5); // expected-warning{{out-of-bound}}
351}
352
353void memcmp2 () {
354  char a[] = {1, 2, 3, 4};
355  char b[1] = { 0 };
356
357  memcmp(a, b, 4); // expected-warning{{out-of-bound}}
358}
359
360void memcmp3 () {
361  char a[] = {1, 2, 3, 4};
362
363  if (memcmp(a, a, 4))
364    (void)*(char*)0; // no-warning
365}
366
367void memcmp4 (char *input) {
368  char a[] = {1, 2, 3, 4};
369
370  if (memcmp(a, input, 4))
371    (void)*(char*)0; // expected-warning{{null}}
372}
373
374void memcmp5 (char *input) {
375  char a[] = {1, 2, 3, 4};
376
377  if (memcmp(a, 0, 0)) // no-warning
378    (void)*(char*)0;   // no-warning
379  if (memcmp(0, a, 0)) // no-warning
380    (void)*(char*)0;   // no-warning
381  if (memcmp(a, input, 0)) // no-warning
382    (void)*(char*)0;   // no-warning
383}
384
385void memcmp6 (char *a, char *b, size_t n) {
386  int result = memcmp(a, b, n);
387  if (result != 0)
388    return;
389  if (n == 0)
390    (void)*(char*)0; // expected-warning{{null}}
391}
392
393int memcmp7 (char *a, size_t x, size_t y, size_t n) {
394  // We used to crash when either of the arguments was unknown.
395  return memcmp(a, &a[x*y], n) +
396         memcmp(&a[x*y], a, n);
397}
398
399//===----------------------------------------------------------------------===
400// bcopy()
401//===----------------------------------------------------------------------===
402
403#define bcopy BUILTIN(bcopy)
404// __builtin_bcopy is not defined with const in Builtins.def.
405void bcopy(/*const*/ void *s1, void *s2, size_t n);
406
407
408void bcopy0 () {
409  char src[] = {1, 2, 3, 4};
410  char dst[4] = {0};
411
412  bcopy(src, dst, 4); // no-warning
413
414  if (dst[0] != 0)
415    (void)*(char*)0; // expected-warning{{null}}
416}
417
418void bcopy1 () {
419  char src[] = {1, 2, 3, 4};
420  char dst[10];
421
422  bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
423}
424
425void bcopy2 () {
426  char src[] = {1, 2, 3, 4};
427  char dst[1];
428
429  bcopy(src, dst, 4); // expected-warning{{overflow}}
430}
431