bstring.c revision 176edba5311f6eff0cad2631449885ddf4fbc9ea
1// 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
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
29void clang_analyzer_eval(int);
30
31//===----------------------------------------------------------------------===
32// memcpy()
33//===----------------------------------------------------------------------===
34
35#ifdef VARIANT
36
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
43#else /* VARIANT */
44
45#define memcpy BUILTIN(memcpy)
46void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
47
48#endif /* VARIANT */
49
50
51void memcpy0 () {
52  char src[] = {1, 2, 3, 4};
53  char dst[4] = {0};
54
55  memcpy(dst, src, 4); // no-warning
56
57  clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
58
59  // 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}}
62}
63
64void memcpy1 () {
65  char src[] = {1, 2, 3, 4};
66  char dst[10];
67
68  memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
69}
70
71void memcpy2 () {
72  char src[] = {1, 2, 3, 4};
73  char dst[1];
74
75  memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
76}
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
89  memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
90}
91
92void memcpy5() {
93  char src[] = {1, 2, 3, 4};
94  char dst[3];
95
96  memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
97}
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
120void memcpy10() {
121  char a[4] = {0};
122  memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
123}
124
125void memcpy11() {
126  char a[4] = {0};
127  memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
128}
129
130void memcpy12() {
131  char a[4] = {0};
132  memcpy(0, a, 0); // no-warning
133}
134
135void memcpy13() {
136  char a[4] = {0};
137  memcpy(a, 0, 0); // no-warning
138}
139
140void memcpy_unknown_size (size_t n) {
141  char a[4], b[4] = {1};
142  clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
143}
144
145void memcpy_unknown_size_warn (size_t n) {
146  char a[4];
147  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)
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  clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
178
179  // 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}}
182}
183
184void mempcpy1 () {
185  char src[] = {1, 2, 3, 4};
186  char dst[10];
187
188  mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
189}
190
191void mempcpy2 () {
192  char src[] = {1, 2, 3, 4};
193  char dst[1];
194
195  mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
196}
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
209  mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
210}
211
212void mempcpy5() {
213  char src[] = {1, 2, 3, 4};
214  char dst[3];
215
216  mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
217}
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};
242  mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
243}
244
245void mempcpy11() {
246  char a[4] = {0};
247  mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
248}
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
260void 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
299void mempcpy_unknown_size_warn (size_t n) {
300  char a[4];
301  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)
303}
304
305void 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
311//===----------------------------------------------------------------------===
312// memmove()
313//===----------------------------------------------------------------------===
314
315#ifdef VARIANT
316
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
322#else /* VARIANT */
323
324#define memmove BUILTIN(memmove)
325void *memmove(void *s1, const void *s2, size_t n);
326
327#endif /* VARIANT */
328
329
330void memmove0 () {
331  char src[] = {1, 2, 3, 4};
332  char dst[4] = {0};
333
334  memmove(dst, src, 4); // no-warning
335
336  clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
337
338  // 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}}
341}
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
354  memmove(dst, src, 4); // expected-warning{{overflow}}
355}
356
357//===----------------------------------------------------------------------===
358// 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
367//
368#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
400  clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
401}
402
403void memcmp4 (char *input) {
404  char a[] = {1, 2, 3, 4};
405
406  clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
407}
408
409void memcmp5 (char *input) {
410  char a[] = {1, 2, 3, 4};
411
412  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}}
415}
416
417void memcmp6 (char *a, char *b, size_t n) {
418  int result = memcmp(a, b, n);
419  if (result != 0)
420    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.
426}
427
428int 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
434//===----------------------------------------------------------------------===
435// 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};
445  char dst[4] = {0};
446
447  bcopy(src, dst, 4); // no-warning
448
449  // 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}}
452}
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
465  bcopy(src, dst, 4); // expected-warning{{overflow}}
466}
467
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}
477