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