]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/string.c
Vendor import of clang trunk r300422:
[FreeBSD/FreeBSD.git] / test / Analysis / string.c
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
2 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
3 // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
4 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -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
27 #define NULL 0
28 typedef typeof(sizeof(int)) size_t;
29
30 void clang_analyzer_eval(int);
31
32 int scanf(const char *restrict format, ...);
33
34 //===----------------------------------------------------------------------===
35 // strlen()
36 //===----------------------------------------------------------------------===
37
38 #define strlen BUILTIN(strlen)
39 size_t strlen(const char *s);
40
41 void strlen_constant0() {
42   clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}}
43 }
44
45 void strlen_constant1() {
46   const char *a = "123";
47   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
48 }
49
50 void strlen_constant2(char x) {
51   char a[] = "123";
52   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
53
54   a[0] = x;
55   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
56 }
57
58 size_t strlen_null() {
59   return strlen(0); // expected-warning{{Null pointer argument in call to string length function}}
60 }
61
62 size_t strlen_fn() {
63   return strlen((char*)&strlen_fn); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}}
64 }
65
66 size_t strlen_nonloc() {
67 label:
68   return strlen((char*)&&label); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}}
69 }
70
71 void strlen_subregion() {
72   struct two_strings { char a[2], b[2]; };
73   extern void use_two_strings(struct two_strings *);
74
75   struct two_strings z;
76   use_two_strings(&z);
77
78   size_t a = strlen(z.a);
79   z.b[0] = 5;
80   size_t b = strlen(z.a);
81   if (a == 0)
82     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
83
84   use_two_strings(&z);
85
86   size_t c = strlen(z.a);
87   if (a == 0)
88     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
89 }
90
91 extern void use_string(char *);
92 void strlen_argument(char *x) {
93   size_t a = strlen(x);
94   size_t b = strlen(x);
95   if (a == 0)
96     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
97
98   use_string(x);
99
100   size_t c = strlen(x);
101   if (a == 0)
102     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
103 }
104
105 extern char global_str[];
106 void strlen_global() {
107   size_t a = strlen(global_str);
108   size_t b = strlen(global_str);
109   if (a == 0) {
110     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
111     // Make sure clang_analyzer_eval does not invalidate globals.
112     clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}}    
113   }
114
115   // Call a function with unknown effects, which should invalidate globals.
116   use_string(0);
117
118   size_t c = strlen(global_str);
119   if (a == 0)
120     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
121 }
122
123 void strlen_indirect(char *x) {
124   size_t a = strlen(x);
125   char *p = x;
126   char **p2 = &p;
127   size_t b = strlen(x);
128   if (a == 0)
129     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
130
131   extern void use_string_ptr(char*const*);
132   use_string_ptr(p2);
133
134   size_t c = strlen(x);
135   if (a == 0)
136     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
137 }
138
139 void strlen_indirect2(char *x) {
140   size_t a = strlen(x);
141   char *p = x;
142   char **p2 = &p;
143   extern void use_string_ptr2(char**);
144   use_string_ptr2(p2);
145
146   size_t c = strlen(x);
147   if (a == 0)
148     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
149 }
150
151 void strlen_liveness(const char *x) {
152   if (strlen(x) < 5)
153     return;
154   clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
155 }
156
157
158 size_t strlenWrapper(const char *str) {
159   return strlen(str);
160 }
161
162 extern void invalidate(char *s);
163
164 void testStrlenCallee() {
165   char str[42];
166   invalidate(str);
167   size_t lenBefore = strlenWrapper(str);
168   invalidate(str);
169   size_t lenAfter = strlenWrapper(str);
170   clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}}
171 }
172
173
174 //===----------------------------------------------------------------------===
175 // strnlen()
176 //===----------------------------------------------------------------------===
177
178 size_t strnlen(const char *s, size_t maxlen);
179
180 void strnlen_constant0() {
181   clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}}
182 }
183
184 void strnlen_constant1() {
185   const char *a = "123";
186   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
187 }
188
189 void strnlen_constant2(char x) {
190   char a[] = "123";
191   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
192   a[0] = x;
193   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}
194 }
195
196 void strnlen_constant4() {
197   clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}}
198 }
199
200 void strnlen_constant5() {
201   const char *a = "123456";
202   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
203 }
204
205 void strnlen_constant6(char x) {
206   char a[] = "123456";
207   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
208   a[0] = x;
209   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}
210 }
211
212 size_t strnlen_null() {
213   return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}}
214 }
215
216 size_t strnlen_fn() {
217   return strnlen((char*)&strlen_fn, 3); // expected-warning{{Argument to string length function is the address of the function 'strlen_fn', which is not a null-terminated string}}
218 }
219
220 size_t strnlen_nonloc() {
221 label:
222   return strnlen((char*)&&label, 3); // expected-warning{{Argument to string length function is the address of the label 'label', which is not a null-terminated string}}
223 }
224
225 void strnlen_zero() {
226   clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}}
227   clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}}
228 }
229
230 size_t strnlen_compound_literal() {
231   // This used to crash because we don't model the string lengths of
232   // compound literals.
233   return strnlen((char[]) { 'a', 'b', 0 }, 1);
234 }
235
236 size_t strnlen_unknown_limit(float f) {
237   // This used to crash because we don't model the integer values of floats.
238   return strnlen("abc", (int)f);
239 }
240
241 void strnlen_is_not_strlen(char *x) {
242   clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}}
243 }
244
245 void strnlen_at_limit(char *x) {
246   size_t len = strnlen(x, 10);
247   clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}}
248   clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}}
249   clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}}
250 }
251
252 void strnlen_at_actual(size_t limit) {
253   size_t len = strnlen("abc", limit);
254   clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}}
255   // This is due to eager assertion in strnlen.
256   if (limit == 0) {
257     clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
258   } else {
259     clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}}
260     clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}}
261   }
262 }
263
264 //===----------------------------------------------------------------------===
265 // strcpy()
266 //===----------------------------------------------------------------------===
267
268 #ifdef VARIANT
269
270 #define __strcpy_chk BUILTIN(__strcpy_chk)
271 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
272
273 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
274
275 #else /* VARIANT */
276
277 #define strcpy BUILTIN(strcpy)
278 char *strcpy(char *restrict s1, const char *restrict s2);
279
280 #endif /* VARIANT */
281
282
283 void strcpy_null_dst(char *x) {
284   strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
285 }
286
287 void strcpy_null_src(char *x) {
288   strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
289 }
290
291 void strcpy_fn(char *x) {
292   strcpy(x, (char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
293 }
294
295 void strcpy_fn_const(char *x) {
296   strcpy(x, (const char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
297 }
298
299 extern int globalInt;
300 void strcpy_effects(char *x, char *y) {
301   char a = x[0];
302   if (globalInt != 42)
303     return;
304
305   clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
306   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
307   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
308   clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
309 }
310
311 void strcpy_overflow(char *y) {
312   char x[4];
313   if (strlen(y) == 4)
314     strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
315 }
316
317 void strcpy_no_overflow(char *y) {
318   char x[4];
319   if (strlen(y) == 3)
320     strcpy(x, y); // no-warning
321 }
322
323 //===----------------------------------------------------------------------===
324 // stpcpy()
325 //===----------------------------------------------------------------------===
326
327 #ifdef VARIANT
328
329 #define __stpcpy_chk BUILTIN(__stpcpy_chk)
330 char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
331
332 #define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
333
334 #else /* VARIANT */
335
336 #define stpcpy BUILTIN(stpcpy)
337 char *stpcpy(char *restrict s1, const char *restrict s2);
338
339 #endif /* VARIANT */
340
341
342 void stpcpy_effect(char *x, char *y) {
343   char a = x[0];
344
345   clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}}
346   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
347   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
348 }
349
350 void stpcpy_overflow(char *y) {
351   char x[4];
352   if (strlen(y) == 4)
353     stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
354 }
355
356 void stpcpy_no_overflow(char *y) {
357   char x[4];
358   if (strlen(y) == 3)
359     stpcpy(x, y); // no-warning
360 }
361
362 //===----------------------------------------------------------------------===
363 // strcat()
364 //===----------------------------------------------------------------------===
365
366 #ifdef VARIANT
367
368 #define __strcat_chk BUILTIN(__strcat_chk)
369 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
370
371 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
372
373 #else /* VARIANT */
374
375 #define strcat BUILTIN(strcat)
376 char *strcat(char *restrict s1, const char *restrict s2);
377
378 #endif /* VARIANT */
379
380
381 void strcat_null_dst(char *x) {
382   strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
383 }
384
385 void strcat_null_src(char *x) {
386   strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
387 }
388
389 void strcat_fn(char *x) {
390   strcat(x, (char*)&strcat_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcat_fn', which is not a null-terminated string}}
391 }
392
393 void strcat_effects(char *y) {
394   char x[8] = "123";
395   size_t orig_len = strlen(x);
396   char a = x[0];
397
398   if (strlen(y) != 4)
399     return;
400
401   clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
402   clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
403 }
404
405 void strcat_overflow_0(char *y) {
406   char x[4] = "12";
407   if (strlen(y) == 4)
408     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
409 }
410
411 void strcat_overflow_1(char *y) {
412   char x[4] = "12";
413   if (strlen(y) == 3)
414     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
415 }
416
417 void strcat_overflow_2(char *y) {
418   char x[4] = "12";
419   if (strlen(y) == 2)
420     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
421 }
422
423 void strcat_no_overflow(char *y) {
424   char x[5] = "12";
425   if (strlen(y) == 2)
426     strcat(x, y); // no-warning
427 }
428
429 void strcat_symbolic_dst_length(char *dst) {
430         strcat(dst, "1234");
431   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
432 }
433
434 void strcat_symbolic_dst_length_taint(char *dst) {
435   scanf("%s", dst); // Taint data.
436   strcat(dst, "1234");
437   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
438 }
439
440 void strcat_unknown_src_length(char *src, int offset) {
441         char dst[8] = "1234";
442         strcat(dst, &src[offset]);
443   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
444 }
445
446 // There is no strcat_unknown_dst_length because if we can't get a symbolic
447 // length for the "before" strlen, we won't be able to set one for "after".
448
449 void strcat_too_big(char *dst, char *src) {
450   // We assume this can never actually happen, so we don't get a warning.
451         if (strlen(dst) != (((size_t)0) - 2))
452                 return;
453         if (strlen(src) != 2)
454                 return;
455         strcat(dst, src);
456 }
457
458
459 //===----------------------------------------------------------------------===
460 // strncpy()
461 //===----------------------------------------------------------------------===
462
463 #ifdef VARIANT
464
465 #define __strncpy_chk BUILTIN(__strncpy_chk)
466 char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
467
468 #define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
469
470 #else /* VARIANT */
471
472 #define strncpy BUILTIN(strncpy)
473 char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
474
475 #endif /* VARIANT */
476
477
478 void strncpy_null_dst(char *x) {
479   strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
480 }
481
482 void strncpy_null_src(char *x) {
483   strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
484 }
485
486 void strncpy_fn(char *x) {
487   strncpy(x, (char*)&strcpy_fn, 5); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
488 }
489
490 void strncpy_effects(char *x, char *y) {
491   char a = x[0];
492
493   clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
494   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
495   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
496 }
497
498 void strncpy_overflow(char *y) {
499   char x[4];
500   if (strlen(y) == 4)
501     strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
502 }
503
504 void strncpy_no_overflow(char *y) {
505   char x[4];
506   if (strlen(y) == 3)
507     strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
508 }
509
510 void strncpy_no_overflow2(char *y, int n) {
511         if (n <= 4)
512                 return;
513
514   char x[4];
515   if (strlen(y) == 3)
516     strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
517 }
518
519 void strncpy_truncate(char *y) {
520   char x[4];
521   if (strlen(y) == 4)
522     strncpy(x, y, 3); // no-warning
523 }
524
525 void strncpy_no_truncate(char *y) {
526   char x[4];
527   if (strlen(y) == 3)
528     strncpy(x, y, 3); // no-warning
529 }
530
531 void strncpy_exactly_matching_buffer(char *y) {
532         char x[4];
533         strncpy(x, y, 4); // no-warning
534
535         // strncpy does not null-terminate, so we have no idea what the strlen is
536         // after this.
537   clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
538 }
539
540 void strncpy_zero(char *src) {
541   char dst[] = "123";
542   strncpy(dst, src, 0); // no-warning
543 }
544
545 void strncpy_empty() {
546   char dst[] = "123";
547   char src[] = "";
548   strncpy(dst, src, 4); // no-warning
549 }
550
551 //===----------------------------------------------------------------------===
552 // strncat()
553 //===----------------------------------------------------------------------===
554
555 #ifdef VARIANT
556
557 #define __strncat_chk BUILTIN(__strncat_chk)
558 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
559
560 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
561
562 #else /* VARIANT */
563
564 #define strncat BUILTIN(strncat)
565 char *strncat(char *restrict s1, const char *restrict s2, size_t n);
566
567 #endif /* VARIANT */
568
569
570 void strncat_null_dst(char *x) {
571   strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
572 }
573
574 void strncat_null_src(char *x) {
575   strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
576 }
577
578 void strncat_fn(char *x) {
579   strncat(x, (char*)&strncat_fn, 4); // expected-warning{{Argument to string copy function is the address of the function 'strncat_fn', which is not a null-terminated string}}
580 }
581
582 void strncat_effects(char *y) {
583   char x[8] = "123";
584   size_t orig_len = strlen(x);
585   char a = x[0];
586
587   if (strlen(y) != 4)
588     return;
589
590   clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
591   clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
592 }
593
594 void strncat_overflow_0(char *y) {
595   char x[4] = "12";
596   if (strlen(y) == 4)
597     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
598 }
599
600 void strncat_overflow_1(char *y) {
601   char x[4] = "12";
602   if (strlen(y) == 3)
603     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
604 }
605
606 void strncat_overflow_2(char *y) {
607   char x[4] = "12";
608   if (strlen(y) == 2)
609     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
610 }
611
612 void strncat_overflow_3(char *y) {
613   char x[4] = "12";
614   if (strlen(y) == 4)
615     strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
616 }
617 void strncat_no_overflow_1(char *y) {
618   char x[5] = "12";
619   if (strlen(y) == 2)
620     strncat(x, y, strlen(y)); // no-warning
621 }
622
623 void strncat_no_overflow_2(char *y) {
624   char x[4] = "12";
625   if (strlen(y) == 4)
626     strncat(x, y, 1); // no-warning
627 }
628
629 void strncat_symbolic_dst_length(char *dst) {
630   strncat(dst, "1234", 5);
631   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
632 }
633
634 void strncat_symbolic_src_length(char *src) {
635   char dst[8] = "1234";
636   strncat(dst, src, 3);
637   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
638
639   char dst2[8] = "1234";
640   strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
641 }
642
643 void strncat_unknown_src_length(char *src, int offset) {
644   char dst[8] = "1234";
645   strncat(dst, &src[offset], 3);
646   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
647
648   char dst2[8] = "1234";
649   strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
650 }
651
652 // There is no strncat_unknown_dst_length because if we can't get a symbolic
653 // length for the "before" strlen, we won't be able to set one for "after".
654
655 void strncat_symbolic_limit(unsigned limit) {
656   char dst[6] = "1234";
657   char src[] = "567";
658   strncat(dst, src, limit); // no-warning
659
660   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
661   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
662 }
663
664 void strncat_unknown_limit(float limit) {
665   char dst[6] = "1234";
666   char src[] = "567";
667   strncat(dst, src, (size_t)limit); // no-warning
668
669   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
670   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
671 }
672
673 void strncat_too_big(char *dst, char *src) {
674   // We assume this will never actually happen, so we don't get a warning.
675   if (strlen(dst) != (((size_t)0) - 2))
676     return;
677   if (strlen(src) != 2)
678     return;
679   strncat(dst, src, 2);
680 }
681
682 void strncat_zero(char *src) {
683   char dst[] = "123";
684   strncat(dst, src, 0); // no-warning
685 }
686
687 void strncat_empty() {
688   char dst[8] = "123";
689   char src[] = "";
690   strncat(dst, src, 4); // no-warning
691 }
692
693 //===----------------------------------------------------------------------===
694 // strcmp()
695 //===----------------------------------------------------------------------===
696
697 #define strcmp BUILTIN(strcmp)
698 int strcmp(const char * s1, const char * s2);
699
700 void strcmp_check_modelling() {
701   char *x = "aa";
702   char *y = "a";
703   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
704   clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}}
705   clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}}
706
707   clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}}
708   clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}}
709   clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}}
710 }
711
712 void strcmp_constant0() {
713   clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
714 }
715
716 void strcmp_constant_and_var_0() {
717   char *x = "123";
718   clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
719 }
720
721 void strcmp_constant_and_var_1() {
722   char *x = "123";
723   clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
724 }
725
726 void strcmp_0() {
727   char *x = "123";
728   char *y = "123";
729   clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
730 }
731
732 void strcmp_1() {
733   char *x = "234";
734   char *y = "123";
735   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
736 }
737
738 void strcmp_2() {
739   char *x = "123";
740   char *y = "234";
741   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
742 }
743
744 void strcmp_null_0() {
745   char *x = NULL;
746   char *y = "123";
747   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
748 }
749
750 void strcmp_null_1() {
751   char *x = "123";
752   char *y = NULL;
753   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
754 }
755
756 void strcmp_diff_length_0() {
757   char *x = "12345";
758   char *y = "234";
759   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
760 }
761
762 void strcmp_diff_length_1() {
763   char *x = "123";
764   char *y = "23456";
765   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
766 }
767
768 void strcmp_diff_length_2() {
769   char *x = "12345";
770   char *y = "123";
771   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
772 }
773
774 void strcmp_diff_length_3() {
775   char *x = "123";
776   char *y = "12345";
777   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
778 }
779
780 void strcmp_embedded_null () {
781         clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
782 }
783
784 void strcmp_unknown_arg (char *unknown) {
785         clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
786 }
787
788 union argument {
789    char *f;
790 };
791
792 void function_pointer_cast_helper(char **a) {
793   strcmp("Hi", *a); // PR24951 crash
794 }
795
796 void strcmp_union_function_pointer_cast(union argument a) {
797   void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper;
798
799   fPtr(&a);
800 }
801
802 //===----------------------------------------------------------------------===
803 // strncmp()
804 //===----------------------------------------------------------------------===
805
806 #define strncmp BUILTIN(strncmp)
807 int strncmp(const char *s1, const char *s2, size_t n);
808
809 void strncmp_check_modelling() {
810   char *x = "aa";
811   char *y = "a";
812   clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}}
813   clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}}
814   clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}}
815
816   clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}}
817   clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}}
818   clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}}
819 }
820
821 void strncmp_constant0() {
822   clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
823 }
824
825 void strncmp_constant_and_var_0() {
826   char *x = "123";
827   clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
828 }
829
830 void strncmp_constant_and_var_1() {
831   char *x = "123";
832   clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
833 }
834
835 void strncmp_0() {
836   char *x = "123";
837   char *y = "123";
838   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
839 }
840
841 void strncmp_1() {
842   char *x = "234";
843   char *y = "123";
844   clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}}
845 }
846
847 void strncmp_2() {
848   char *x = "123";
849   char *y = "234";
850   clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}}
851 }
852
853 void strncmp_null_0() {
854   char *x = NULL;
855   char *y = "123";
856   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
857 }
858
859 void strncmp_null_1() {
860   char *x = "123";
861   char *y = NULL;
862   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
863 }
864
865 void strncmp_diff_length_0() {
866   char *x = "12345";
867   char *y = "234";
868   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
869 }
870
871 void strncmp_diff_length_1() {
872   char *x = "123";
873   char *y = "23456";
874   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
875 }
876
877 void strncmp_diff_length_2() {
878   char *x = "12345";
879   char *y = "123";
880   clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}}
881 }
882
883 void strncmp_diff_length_3() {
884   char *x = "123";
885   char *y = "12345";
886   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
887 }
888
889 void strncmp_diff_length_4() {
890   char *x = "123";
891   char *y = "12345";
892   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
893 }
894
895 void strncmp_diff_length_5() {
896   char *x = "012";
897   char *y = "12345";
898   clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}}
899 }
900
901 void strncmp_diff_length_6() {
902   char *x = "234";
903   char *y = "12345";
904   clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}}
905 }
906
907 void strncmp_embedded_null () {
908         clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
909 }
910
911 //===----------------------------------------------------------------------===
912 // strcasecmp()
913 //===----------------------------------------------------------------------===
914
915 #define strcasecmp BUILTIN(strcasecmp)
916 int strcasecmp(const char *s1, const char *s2);
917
918 void strcasecmp_check_modelling() {
919   char *x = "aa";
920   char *y = "a";
921   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
922   clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}}
923   clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}}
924
925   clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}}
926   clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}}
927   clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}}
928 }
929
930 void strcasecmp_constant0() {
931   clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
932 }
933
934 void strcasecmp_constant_and_var_0() {
935   char *x = "abc";
936   clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
937 }
938
939 void strcasecmp_constant_and_var_1() {
940   char *x = "abc";
941   clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
942 }
943
944 void strcasecmp_0() {
945   char *x = "abc";
946   char *y = "Abc";
947   clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
948 }
949
950 void strcasecmp_1() {
951   char *x = "Bcd";
952   char *y = "abc";
953   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
954 }
955
956 void strcasecmp_2() {
957   char *x = "abc";
958   char *y = "Bcd";
959   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
960 }
961
962 void strcasecmp_null_0() {
963   char *x = NULL;
964   char *y = "123";
965   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
966 }
967
968 void strcasecmp_null_1() {
969   char *x = "123";
970   char *y = NULL;
971   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
972 }
973
974 void strcasecmp_diff_length_0() {
975   char *x = "abcde";
976   char *y = "aBd";
977   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
978 }
979
980 void strcasecmp_diff_length_1() {
981   char *x = "abc";
982   char *y = "aBdef";
983   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
984 }
985
986 void strcasecmp_diff_length_2() {
987   char *x = "aBcDe";
988   char *y = "abc";
989   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
990 }
991
992 void strcasecmp_diff_length_3() {
993   char *x = "aBc";
994   char *y = "abcde";
995   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
996 }
997
998 void strcasecmp_embedded_null () {
999         clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
1000 }
1001
1002 //===----------------------------------------------------------------------===
1003 // strncasecmp()
1004 //===----------------------------------------------------------------------===
1005
1006 #define strncasecmp BUILTIN(strncasecmp)
1007 int strncasecmp(const char *s1, const char *s2, size_t n);
1008
1009 void strncasecmp_check_modelling() {
1010   char *x = "aa";
1011   char *y = "a";
1012   clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}}
1013   clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}}
1014   clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}}
1015
1016   clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}}
1017   clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}}
1018   clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}}
1019 }
1020
1021 void strncasecmp_constant0() {
1022   clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
1023 }
1024
1025 void strncasecmp_constant_and_var_0() {
1026   char *x = "abc";
1027   clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
1028 }
1029
1030 void strncasecmp_constant_and_var_1() {
1031   char *x = "abc";
1032   clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
1033 }
1034
1035 void strncasecmp_0() {
1036   char *x = "abc";
1037   char *y = "Abc";
1038   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
1039 }
1040
1041 void strncasecmp_1() {
1042   char *x = "Bcd";
1043   char *y = "abc";
1044   clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}}
1045 }
1046
1047 void strncasecmp_2() {
1048   char *x = "abc";
1049   char *y = "Bcd";
1050   clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}}
1051 }
1052
1053 void strncasecmp_null_0() {
1054   char *x = NULL;
1055   char *y = "123";
1056   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
1057 }
1058
1059 void strncasecmp_null_1() {
1060   char *x = "123";
1061   char *y = NULL;
1062   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
1063 }
1064
1065 void strncasecmp_diff_length_0() {
1066   char *x = "abcde";
1067   char *y = "aBd";
1068   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
1069 }
1070
1071 void strncasecmp_diff_length_1() {
1072   char *x = "abc";
1073   char *y = "aBdef";
1074   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
1075 }
1076
1077 void strncasecmp_diff_length_2() {
1078   char *x = "aBcDe";
1079   char *y = "abc";
1080   clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}}
1081 }
1082
1083 void strncasecmp_diff_length_3() {
1084   char *x = "aBc";
1085   char *y = "abcde";
1086   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
1087 }
1088
1089 void strncasecmp_diff_length_4() {
1090   char *x = "abcde";
1091   char *y = "aBc";
1092   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
1093 }
1094
1095 void strncasecmp_diff_length_5() {
1096   char *x = "abcde";
1097   char *y = "aBd";
1098   clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}}
1099 }
1100
1101 void strncasecmp_diff_length_6() {
1102   char *x = "aBDe";
1103   char *y = "abc";
1104   clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}}
1105 }
1106
1107 void strncasecmp_embedded_null () {
1108         clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
1109 }
1110
1111 //===----------------------------------------------------------------------===
1112 // strsep()
1113 //===----------------------------------------------------------------------===
1114
1115 char *strsep(char **stringp, const char *delim);
1116
1117 void strsep_null_delim(char *s) {
1118   strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}}
1119 }
1120
1121 void strsep_null_search() {
1122   strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}}
1123 }
1124
1125 void strsep_return_original_pointer(char *s) {
1126   char *original = s;
1127   char *result = strsep(&s, ""); // no-warning
1128   clang_analyzer_eval(original == result); // expected-warning{{TRUE}}
1129 }
1130
1131 void strsep_null_string() {
1132   char *s = NULL;
1133   char *result = strsep(&s, ""); // no-warning
1134   clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}}
1135 }
1136
1137 void strsep_changes_input_pointer(char *s) {
1138   char *original = s;
1139   strsep(&s, ""); // no-warning
1140   clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}}
1141   clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}}
1142
1143   // Check that the value is symbolic.
1144   if (s == NULL) {
1145     clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}}
1146   }
1147 }
1148
1149 void strsep_changes_input_string() {
1150   char str[] = "abc";
1151
1152   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}}
1153
1154   char *s = str;
1155   strsep(&s, "b"); // no-warning
1156
1157   // The real strsep will change the first delimiter it finds into a NUL
1158   // character. For now, we just model the invalidation.
1159   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}}
1160 }
1161
1162 //===----------------------------------------------------------------------===
1163 // FIXMEs
1164 //===----------------------------------------------------------------------===
1165
1166 // The analyzer_eval call below should evaluate to true. We are being too 
1167 // aggressive in marking the (length of) src symbol dead. The length of dst 
1168 // depends on src. This could be explicitely specified in the checker or the 
1169 // logic for handling MetadataSymbol in SymbolManager needs to change.
1170 void strcat_symbolic_src_length(char *src) {
1171         char dst[8] = "1234";
1172         strcat(dst, src);
1173   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
1174 }
1175
1176 // The analyzer_eval call below should evaluate to true. Most likely the same
1177 // issue as the test above.
1178 void strncpy_exactly_matching_buffer2(char *y) {
1179         if (strlen(y) >= 4)
1180                 return;
1181
1182         char x[4];
1183         strncpy(x, y, 4); // no-warning
1184
1185         // This time, we know that y fits in x anyway.
1186   clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
1187 }