1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,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,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
3 // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,unix.Malloc,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,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
5 // RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
6 
7 //===----------------------------------------------------------------------===
8 // Declarations
9 //===----------------------------------------------------------------------===
10 
11 // Some functions are so similar to each other that they follow the same code
12 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
13 // defined, make sure to use the variants instead to make sure they are still
14 // checked by the analyzer.
15 
16 // Some functions are implemented as builtins. These should be #defined as
17 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
18 
19 // Functions that have variants and are also available as builtins should be
20 // declared carefully! See memcpy() for an example.
21 
22 #ifdef USE_BUILTINS
23 # define BUILTIN(f) __builtin_ ## f
24 #else /* USE_BUILTINS */
25 # define BUILTIN(f) f
26 #endif /* USE_BUILTINS */
27 
28 #define NULL 0
29 typedef typeof(sizeof(int)) size_t;
30 
31 void clang_analyzer_eval(int);
32 
33 int scanf(const char *restrict format, ...);
34 
35 //===----------------------------------------------------------------------===
36 // strlen()
37 //===----------------------------------------------------------------------===
38 
39 #define strlen BUILTIN(strlen)
40 size_t strlen(const char *s);
41 
42 void strlen_constant0() {
43   clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}}
44 }
45 
46 void strlen_constant1() {
47   const char *a = "123";
48   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
49 }
50 
51 void strlen_constant2(char x) {
52   char a[] = "123";
53   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
54 
55   a[0] = x;
56   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
57 }
58 
59 size_t strlen_null() {
60   return strlen(0); // expected-warning{{Null pointer argument in call to string length function}}
61 }
62 
63 size_t strlen_fn() {
64   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}}
65 }
66 
67 size_t strlen_nonloc() {
68 label:
69   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}}
70 }
71 
72 void strlen_subregion() {
73   struct two_strings { char a[2], b[2]; };
74   extern void use_two_strings(struct two_strings *);
75 
76   struct two_strings z;
77   use_two_strings(&z);
78 
79   size_t a = strlen(z.a);
80   z.b[0] = 5;
81   size_t b = strlen(z.a);
82   if (a == 0)
83     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
84 
85   use_two_strings(&z);
86 
87   size_t c = strlen(z.a);
88   if (a == 0)
89     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
90 }
91 
92 extern void use_string(char *);
93 void strlen_argument(char *x) {
94   size_t a = strlen(x);
95   size_t b = strlen(x);
96   if (a == 0)
97     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
98 
99   use_string(x);
100 
101   size_t c = strlen(x);
102   if (a == 0)
103     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
104 }
105 
106 extern char global_str[];
107 void strlen_global() {
108   size_t a = strlen(global_str);
109   size_t b = strlen(global_str);
110   if (a == 0) {
111     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
112     // Make sure clang_analyzer_eval does not invalidate globals.
113     clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}}
114   }
115 
116   // Call a function with unknown effects, which should invalidate globals.
117   use_string(0);
118 
119   size_t c = strlen(global_str);
120   if (a == 0)
121     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
122 }
123 
124 void strlen_indirect(char *x) {
125   size_t a = strlen(x);
126   char *p = x;
127   char **p2 = &p;
128   size_t b = strlen(x);
129   if (a == 0)
130     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
131 
132   extern void use_string_ptr(char*const*);
133   use_string_ptr(p2);
134 
135   size_t c = strlen(x);
136   if (a == 0)
137     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
138 }
139 
140 void strlen_indirect2(char *x) {
141   size_t a = strlen(x);
142   char *p = x;
143   char **p2 = &p;
144   extern void use_string_ptr2(char**);
145   use_string_ptr2(p2);
146 
147   size_t c = strlen(x);
148   if (a == 0)
149     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
150 }
151 
152 void strlen_liveness(const char *x) {
153   if (strlen(x) < 5)
154     return;
155   clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
156 }
157 
158 
159 size_t strlenWrapper(const char *str) {
160   return strlen(str);
161 }
162 
163 extern void invalidate(char *s);
164 
165 void testStrlenCallee() {
166   char str[42];
167   invalidate(str);
168   size_t lenBefore = strlenWrapper(str);
169   invalidate(str);
170   size_t lenAfter = strlenWrapper(str);
171   clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}}
172 }
173 
174 
175 //===----------------------------------------------------------------------===
176 // strnlen()
177 //===----------------------------------------------------------------------===
178 
179 size_t strnlen(const char *s, size_t maxlen);
180 
181 void strnlen_constant0() {
182   clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}}
183 }
184 
185 void strnlen_constant1() {
186   const char *a = "123";
187   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
188 }
189 
190 void strnlen_constant2(char x) {
191   char a[] = "123";
192   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
193   a[0] = x;
194   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}
195 }
196 
197 void strnlen_constant4() {
198   clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}}
199 }
200 
201 void strnlen_constant5() {
202   const char *a = "123456";
203   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
204 }
205 
206 void strnlen_constant6(char x) {
207   char a[] = "123456";
208   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
209   a[0] = x;
210   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}
211 }
212 
213 size_t strnlen_null() {
214   return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}}
215 }
216 
217 size_t strnlen_fn() {
218   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}}
219 }
220 
221 size_t strnlen_nonloc() {
222 label:
223   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}}
224 }
225 
226 void strnlen_zero() {
227   clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}}
228   clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}}
229 }
230 
231 size_t strnlen_compound_literal() {
232   // This used to crash because we don't model the string lengths of
233   // compound literals.
234   return strnlen((char[]) { 'a', 'b', 0 }, 1);
235 }
236 
237 size_t strnlen_unknown_limit(float f) {
238   // This used to crash because we don't model the integer values of floats.
239   return strnlen("abc", (int)f);
240 }
241 
242 void strnlen_is_not_strlen(char *x) {
243   clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}}
244 }
245 
246 void strnlen_at_limit(char *x) {
247   size_t len = strnlen(x, 10);
248   clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}}
249   clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}}
250   clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}}
251 }
252 
253 void strnlen_at_actual(size_t limit) {
254   size_t len = strnlen("abc", limit);
255   clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}}
256   // This is due to eager assertion in strnlen.
257   if (limit == 0) {
258     clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
259   } else {
260     clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}}
261     clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}}
262   }
263 }
264 
265 //===----------------------------------------------------------------------===
266 // strcpy()
267 //===----------------------------------------------------------------------===
268 
269 #ifdef VARIANT
270 
271 #define __strcpy_chk BUILTIN(__strcpy_chk)
272 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
273 
274 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
275 
276 #else /* VARIANT */
277 
278 #define strcpy BUILTIN(strcpy)
279 char *strcpy(char *restrict s1, const char *restrict s2);
280 
281 #endif /* VARIANT */
282 
283 
284 void strcpy_null_dst(char *x) {
285   strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
286 }
287 
288 void strcpy_null_src(char *x) {
289   strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
290 }
291 
292 void strcpy_fn(char *x) {
293   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}}
294 }
295 
296 void strcpy_fn_const(char *x) {
297   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}}
298 }
299 
300 extern int globalInt;
301 void strcpy_effects(char *x, char *y) {
302   char a = x[0];
303   if (globalInt != 42)
304     return;
305 
306   clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
307   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
308   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
309   clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
310 }
311 
312 void strcpy_overflow(char *y) {
313   char x[4];
314   if (strlen(y) == 4)
315     strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
316 }
317 
318 void strcpy_no_overflow(char *y) {
319   char x[4];
320   if (strlen(y) == 3)
321     strcpy(x, y); // no-warning
322 }
323 
324 //===----------------------------------------------------------------------===
325 // stpcpy()
326 //===----------------------------------------------------------------------===
327 
328 #ifdef VARIANT
329 
330 #define __stpcpy_chk BUILTIN(__stpcpy_chk)
331 char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
332 
333 #define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
334 
335 #else /* VARIANT */
336 
337 #define stpcpy BUILTIN(stpcpy)
338 char *stpcpy(char *restrict s1, const char *restrict s2);
339 
340 #endif /* VARIANT */
341 
342 
343 void stpcpy_effect(char *x, char *y) {
344   char a = x[0];
345 
346   clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}}
347   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
348   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
349 }
350 
351 void stpcpy_overflow(char *y) {
352   char x[4];
353   if (strlen(y) == 4)
354     stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
355 }
356 
357 void stpcpy_no_overflow(char *y) {
358   char x[4];
359   if (strlen(y) == 3)
360     stpcpy(x, y); // no-warning
361 }
362 
363 //===----------------------------------------------------------------------===
364 // strcat()
365 //===----------------------------------------------------------------------===
366 
367 #ifdef VARIANT
368 
369 #define __strcat_chk BUILTIN(__strcat_chk)
370 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
371 
372 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
373 
374 #else /* VARIANT */
375 
376 #define strcat BUILTIN(strcat)
377 char *strcat(char *restrict s1, const char *restrict s2);
378 
379 #endif /* VARIANT */
380 
381 
382 void strcat_null_dst(char *x) {
383   strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
384 }
385 
386 void strcat_null_src(char *x) {
387   strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
388 }
389 
390 void strcat_fn(char *x) {
391   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}}
392 }
393 
394 void strcat_effects(char *y) {
395   char x[8] = "123";
396   size_t orig_len = strlen(x);
397   char a = x[0];
398 
399   if (strlen(y) != 4)
400     return;
401 
402   clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
403   clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
404 }
405 
406 void strcat_overflow_0(char *y) {
407   char x[4] = "12";
408   if (strlen(y) == 4)
409     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
410 }
411 
412 void strcat_overflow_1(char *y) {
413   char x[4] = "12";
414   if (strlen(y) == 3)
415     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
416 }
417 
418 void strcat_overflow_2(char *y) {
419   char x[4] = "12";
420   if (strlen(y) == 2)
421     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
422 }
423 
424 void strcat_no_overflow(char *y) {
425   char x[5] = "12";
426   if (strlen(y) == 2)
427     strcat(x, y); // no-warning
428 }
429 
430 void strcat_symbolic_dst_length(char *dst) {
431 	strcat(dst, "1234");
432   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
433 }
434 
435 void strcat_symbolic_dst_length_taint(char *dst) {
436   scanf("%s", dst); // Taint data.
437   strcat(dst, "1234");
438   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
439 }
440 
441 void strcat_unknown_src_length(char *src, int offset) {
442 	char dst[8] = "1234";
443 	strcat(dst, &src[offset]);
444   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
445 }
446 
447 // There is no strcat_unknown_dst_length because if we can't get a symbolic
448 // length for the "before" strlen, we won't be able to set one for "after".
449 
450 void strcat_too_big(char *dst, char *src) {
451   // We assume this can never actually happen, so we don't get a warning.
452 	if (strlen(dst) != (((size_t)0) - 2))
453 		return;
454 	if (strlen(src) != 2)
455 		return;
456 	strcat(dst, src);
457 }
458 
459 
460 //===----------------------------------------------------------------------===
461 // strncpy()
462 //===----------------------------------------------------------------------===
463 
464 #ifdef VARIANT
465 
466 #define __strncpy_chk BUILTIN(__strncpy_chk)
467 char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
468 
469 #define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
470 
471 #else /* VARIANT */
472 
473 #define strncpy BUILTIN(strncpy)
474 char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
475 
476 #endif /* VARIANT */
477 
478 
479 void strncpy_null_dst(char *x) {
480   strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
481 }
482 
483 void strncpy_null_src(char *x) {
484   strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
485 }
486 
487 void strncpy_fn(char *x) {
488   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}}
489 }
490 
491 void strncpy_effects(char *x, char *y) {
492   char a = x[0];
493 
494   clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
495   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
496   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
497 }
498 
499 void strncpy_overflow(char *y) {
500   char x[4];
501   if (strlen(y) == 4)
502     strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
503 }
504 
505 void strncpy_no_overflow(char *y) {
506   char x[4];
507   if (strlen(y) == 3)
508     strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
509 }
510 
511 void strncpy_no_overflow2(char *y, int n) {
512 	if (n <= 4)
513 		return;
514 
515   char x[4];
516   if (strlen(y) == 3)
517     strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
518 }
519 
520 void strncpy_truncate(char *y) {
521   char x[4];
522   if (strlen(y) == 4)
523     strncpy(x, y, 3); // no-warning
524 }
525 
526 void strncpy_no_truncate(char *y) {
527   char x[4];
528   if (strlen(y) == 3)
529     strncpy(x, y, 3); // no-warning
530 }
531 
532 void strncpy_exactly_matching_buffer(char *y) {
533 	char x[4];
534 	strncpy(x, y, 4); // no-warning
535 
536 	// strncpy does not null-terminate, so we have no idea what the strlen is
537 	// after this.
538   clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
539 }
540 
541 void strncpy_zero(char *src) {
542   char dst[] = "123";
543   strncpy(dst, src, 0); // no-warning
544 }
545 
546 void strncpy_empty() {
547   char dst[] = "123";
548   char src[] = "";
549   strncpy(dst, src, 4); // no-warning
550 }
551 
552 //===----------------------------------------------------------------------===
553 // strncat()
554 //===----------------------------------------------------------------------===
555 
556 #ifdef VARIANT
557 
558 #define __strncat_chk BUILTIN(__strncat_chk)
559 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
560 
561 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
562 
563 #else /* VARIANT */
564 
565 #define strncat BUILTIN(strncat)
566 char *strncat(char *restrict s1, const char *restrict s2, size_t n);
567 
568 #endif /* VARIANT */
569 
570 
571 void strncat_null_dst(char *x) {
572   strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
573 }
574 
575 void strncat_null_src(char *x) {
576   strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
577 }
578 
579 void strncat_fn(char *x) {
580   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}}
581 }
582 
583 void strncat_effects(char *y) {
584   char x[8] = "123";
585   size_t orig_len = strlen(x);
586   char a = x[0];
587 
588   if (strlen(y) != 4)
589     return;
590 
591   clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
592   clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
593 }
594 
595 void strncat_overflow_0(char *y) {
596   char x[4] = "12";
597   if (strlen(y) == 4)
598     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
599 }
600 
601 void strncat_overflow_1(char *y) {
602   char x[4] = "12";
603   if (strlen(y) == 3)
604     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
605 }
606 
607 void strncat_overflow_2(char *y) {
608   char x[4] = "12";
609   if (strlen(y) == 2)
610     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
611 }
612 
613 void strncat_overflow_3(char *y) {
614   char x[4] = "12";
615   if (strlen(y) == 4)
616     strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
617 }
618 void strncat_no_overflow_1(char *y) {
619   char x[5] = "12";
620   if (strlen(y) == 2)
621     strncat(x, y, strlen(y)); // no-warning
622 }
623 
624 void strncat_no_overflow_2(char *y) {
625   char x[4] = "12";
626   if (strlen(y) == 4)
627     strncat(x, y, 1); // no-warning
628 }
629 
630 void strncat_symbolic_dst_length(char *dst) {
631   strncat(dst, "1234", 5);
632   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
633 }
634 
635 void strncat_symbolic_src_length(char *src) {
636   char dst[8] = "1234";
637   strncat(dst, src, 3);
638   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
639 
640   char dst2[8] = "1234";
641   strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
642 }
643 
644 void strncat_unknown_src_length(char *src, int offset) {
645   char dst[8] = "1234";
646   strncat(dst, &src[offset], 3);
647   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
648 
649   char dst2[8] = "1234";
650   strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
651 }
652 
653 // There is no strncat_unknown_dst_length because if we can't get a symbolic
654 // length for the "before" strlen, we won't be able to set one for "after".
655 
656 void strncat_symbolic_limit(unsigned limit) {
657   char dst[6] = "1234";
658   char src[] = "567";
659   strncat(dst, src, limit); // no-warning
660 
661   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
662   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
663 }
664 
665 void strncat_unknown_limit(float limit) {
666   char dst[6] = "1234";
667   char src[] = "567";
668   strncat(dst, src, (size_t)limit); // no-warning
669 
670   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
671   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
672 }
673 
674 void strncat_too_big(char *dst, char *src) {
675   // We assume this will never actually happen, so we don't get a warning.
676   if (strlen(dst) != (((size_t)0) - 2))
677     return;
678   if (strlen(src) != 2)
679     return;
680   strncat(dst, src, 2);
681 }
682 
683 void strncat_zero(char *src) {
684   char dst[] = "123";
685   strncat(dst, src, 0); // no-warning
686 }
687 
688 void strncat_empty() {
689   char dst[8] = "123";
690   char src[] = "";
691   strncat(dst, src, 4); // no-warning
692 }
693 
694 //===----------------------------------------------------------------------===
695 // strcmp()
696 //===----------------------------------------------------------------------===
697 
698 #define strcmp BUILTIN(strcmp)
699 int strcmp(const char * s1, const char * s2);
700 
701 void strcmp_check_modelling() {
702   char *x = "aa";
703   char *y = "a";
704   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
705   clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}}
706   clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}}
707 
708   clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}}
709   clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}}
710   clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}}
711 }
712 
713 void strcmp_constant0() {
714   clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
715 }
716 
717 void strcmp_constant_and_var_0() {
718   char *x = "123";
719   clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
720 }
721 
722 void strcmp_constant_and_var_1() {
723   char *x = "123";
724   clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
725 }
726 
727 void strcmp_0() {
728   char *x = "123";
729   char *y = "123";
730   clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
731 }
732 
733 void strcmp_1() {
734   char *x = "234";
735   char *y = "123";
736   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
737 }
738 
739 void strcmp_2() {
740   char *x = "123";
741   char *y = "234";
742   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
743 }
744 
745 void strcmp_null_0() {
746   char *x = NULL;
747   char *y = "123";
748   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
749 }
750 
751 void strcmp_null_1() {
752   char *x = "123";
753   char *y = NULL;
754   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
755 }
756 
757 void strcmp_diff_length_0() {
758   char *x = "12345";
759   char *y = "234";
760   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
761 }
762 
763 void strcmp_diff_length_1() {
764   char *x = "123";
765   char *y = "23456";
766   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
767 }
768 
769 void strcmp_diff_length_2() {
770   char *x = "12345";
771   char *y = "123";
772   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
773 }
774 
775 void strcmp_diff_length_3() {
776   char *x = "123";
777   char *y = "12345";
778   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
779 }
780 
781 void strcmp_embedded_null () {
782 	clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
783 }
784 
785 void strcmp_unknown_arg (char *unknown) {
786 	clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
787 }
788 
789 union argument {
790    char *f;
791 };
792 
793 void function_pointer_cast_helper(char **a) {
794   strcmp("Hi", *a); // PR24951 crash
795 }
796 
797 void strcmp_union_function_pointer_cast(union argument a) {
798   void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper;
799 
800   fPtr(&a);
801 }
802 
803 //===----------------------------------------------------------------------===
804 // strncmp()
805 //===----------------------------------------------------------------------===
806 
807 #define strncmp BUILTIN(strncmp)
808 int strncmp(const char *s1, const char *s2, size_t n);
809 
810 void strncmp_check_modelling() {
811   char *x = "aa";
812   char *y = "a";
813   clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}}
814   clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}}
815   clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}}
816 
817   clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}}
818   clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}}
819   clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}}
820 }
821 
822 void strncmp_constant0() {
823   clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
824 }
825 
826 void strncmp_constant_and_var_0() {
827   char *x = "123";
828   clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
829 }
830 
831 void strncmp_constant_and_var_1() {
832   char *x = "123";
833   clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
834 }
835 
836 void strncmp_0() {
837   char *x = "123";
838   char *y = "123";
839   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
840 }
841 
842 void strncmp_1() {
843   char *x = "234";
844   char *y = "123";
845   clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}}
846 }
847 
848 void strncmp_2() {
849   char *x = "123";
850   char *y = "234";
851   clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}}
852 }
853 
854 void strncmp_null_0() {
855   char *x = NULL;
856   char *y = "123";
857   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
858 }
859 
860 void strncmp_null_1() {
861   char *x = "123";
862   char *y = NULL;
863   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
864 }
865 
866 void strncmp_diff_length_0() {
867   char *x = "12345";
868   char *y = "234";
869   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
870 }
871 
872 void strncmp_diff_length_1() {
873   char *x = "123";
874   char *y = "23456";
875   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
876 }
877 
878 void strncmp_diff_length_2() {
879   char *x = "12345";
880   char *y = "123";
881   clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}}
882 }
883 
884 void strncmp_diff_length_3() {
885   char *x = "123";
886   char *y = "12345";
887   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
888 }
889 
890 void strncmp_diff_length_4() {
891   char *x = "123";
892   char *y = "12345";
893   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
894 }
895 
896 void strncmp_diff_length_5() {
897   char *x = "012";
898   char *y = "12345";
899   clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}}
900 }
901 
902 void strncmp_diff_length_6() {
903   char *x = "234";
904   char *y = "12345";
905   clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}}
906 }
907 
908 void strncmp_embedded_null () {
909 	clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
910 }
911 
912 //===----------------------------------------------------------------------===
913 // strcasecmp()
914 //===----------------------------------------------------------------------===
915 
916 #define strcasecmp BUILTIN(strcasecmp)
917 int strcasecmp(const char *s1, const char *s2);
918 
919 void strcasecmp_check_modelling() {
920   char *x = "aa";
921   char *y = "a";
922   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
923   clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}}
924   clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}}
925 
926   clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}}
927   clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}}
928   clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}}
929 }
930 
931 void strcasecmp_constant0() {
932   clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
933 }
934 
935 void strcasecmp_constant_and_var_0() {
936   char *x = "abc";
937   clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
938 }
939 
940 void strcasecmp_constant_and_var_1() {
941   char *x = "abc";
942   clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
943 }
944 
945 void strcasecmp_0() {
946   char *x = "abc";
947   char *y = "Abc";
948   clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
949 }
950 
951 void strcasecmp_1() {
952   char *x = "Bcd";
953   char *y = "abc";
954   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
955 }
956 
957 void strcasecmp_2() {
958   char *x = "abc";
959   char *y = "Bcd";
960   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
961 }
962 
963 void strcasecmp_null_0() {
964   char *x = NULL;
965   char *y = "123";
966   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
967 }
968 
969 void strcasecmp_null_1() {
970   char *x = "123";
971   char *y = NULL;
972   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
973 }
974 
975 void strcasecmp_diff_length_0() {
976   char *x = "abcde";
977   char *y = "aBd";
978   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
979 }
980 
981 void strcasecmp_diff_length_1() {
982   char *x = "abc";
983   char *y = "aBdef";
984   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
985 }
986 
987 void strcasecmp_diff_length_2() {
988   char *x = "aBcDe";
989   char *y = "abc";
990   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
991 }
992 
993 void strcasecmp_diff_length_3() {
994   char *x = "aBc";
995   char *y = "abcde";
996   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
997 }
998 
999 void strcasecmp_embedded_null () {
1000 	clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
1001 }
1002 
1003 //===----------------------------------------------------------------------===
1004 // strncasecmp()
1005 //===----------------------------------------------------------------------===
1006 
1007 #define strncasecmp BUILTIN(strncasecmp)
1008 int strncasecmp(const char *s1, const char *s2, size_t n);
1009 
1010 void strncasecmp_check_modelling() {
1011   char *x = "aa";
1012   char *y = "a";
1013   clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}}
1014   clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}}
1015   clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}}
1016 
1017   clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}}
1018   clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}}
1019   clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}}
1020 }
1021 
1022 void strncasecmp_constant0() {
1023   clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
1024 }
1025 
1026 void strncasecmp_constant_and_var_0() {
1027   char *x = "abc";
1028   clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
1029 }
1030 
1031 void strncasecmp_constant_and_var_1() {
1032   char *x = "abc";
1033   clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
1034 }
1035 
1036 void strncasecmp_0() {
1037   char *x = "abc";
1038   char *y = "Abc";
1039   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
1040 }
1041 
1042 void strncasecmp_1() {
1043   char *x = "Bcd";
1044   char *y = "abc";
1045   clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}}
1046 }
1047 
1048 void strncasecmp_2() {
1049   char *x = "abc";
1050   char *y = "Bcd";
1051   clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}}
1052 }
1053 
1054 void strncasecmp_null_0() {
1055   char *x = NULL;
1056   char *y = "123";
1057   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
1058 }
1059 
1060 void strncasecmp_null_1() {
1061   char *x = "123";
1062   char *y = NULL;
1063   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
1064 }
1065 
1066 void strncasecmp_diff_length_0() {
1067   char *x = "abcde";
1068   char *y = "aBd";
1069   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
1070 }
1071 
1072 void strncasecmp_diff_length_1() {
1073   char *x = "abc";
1074   char *y = "aBdef";
1075   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
1076 }
1077 
1078 void strncasecmp_diff_length_2() {
1079   char *x = "aBcDe";
1080   char *y = "abc";
1081   clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}}
1082 }
1083 
1084 void strncasecmp_diff_length_3() {
1085   char *x = "aBc";
1086   char *y = "abcde";
1087   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
1088 }
1089 
1090 void strncasecmp_diff_length_4() {
1091   char *x = "abcde";
1092   char *y = "aBc";
1093   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
1094 }
1095 
1096 void strncasecmp_diff_length_5() {
1097   char *x = "abcde";
1098   char *y = "aBd";
1099   clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}}
1100 }
1101 
1102 void strncasecmp_diff_length_6() {
1103   char *x = "aBDe";
1104   char *y = "abc";
1105   clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}}
1106 }
1107 
1108 void strncasecmp_embedded_null () {
1109 	clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
1110 }
1111 
1112 //===----------------------------------------------------------------------===
1113 // strsep()
1114 //===----------------------------------------------------------------------===
1115 
1116 char *strsep(char **stringp, const char *delim);
1117 
1118 void strsep_null_delim(char *s) {
1119   strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}}
1120 }
1121 
1122 void strsep_null_search() {
1123   strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}}
1124 }
1125 
1126 void strsep_return_original_pointer(char *s) {
1127   char *original = s;
1128   char *result = strsep(&s, ""); // no-warning
1129   clang_analyzer_eval(original == result); // expected-warning{{TRUE}}
1130 }
1131 
1132 void strsep_null_string() {
1133   char *s = NULL;
1134   char *result = strsep(&s, ""); // no-warning
1135   clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}}
1136 }
1137 
1138 void strsep_changes_input_pointer(char *s) {
1139   char *original = s;
1140   strsep(&s, ""); // no-warning
1141   clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}}
1142   clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}}
1143 
1144   // Check that the value is symbolic.
1145   if (s == NULL) {
1146     clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}}
1147   }
1148 }
1149 
1150 void strsep_changes_input_string() {
1151   char str[] = "abc";
1152 
1153   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}}
1154 
1155   char *s = str;
1156   strsep(&s, "b"); // no-warning
1157 
1158   // The real strsep will change the first delimiter it finds into a NUL
1159   // character. For now, we just model the invalidation.
1160   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}}
1161 }
1162 
1163 //===----------------------------------------------------------------------===
1164 // memset()
1165 //===----------------------------------------------------------------------===
1166 
1167 void *memset(void *dest, int ch, size_t count);
1168 
1169 void *malloc(size_t size);
1170 void free(void *);
1171 
1172 void memset1_char_array_null() {
1173   char str[] = "abcd";
1174   clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
1175   memset(str, '\0', 2);
1176   clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
1177 }
1178 
1179 void memset2_char_array_null() {
1180   char str[] = "abcd";
1181   clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
1182   memset(str, '\0', strlen(str) + 1);
1183   clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
1184   clang_analyzer_eval(str[2] == 0);      // expected-warning{{TRUE}}
1185 }
1186 
1187 void memset3_char_malloc_null() {
1188   char *str = (char *)malloc(10 * sizeof(char));
1189   memset(str + 1, '\0', 8);
1190   clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}}
1191   free(str);
1192 }
1193 
1194 void memset4_char_malloc_null() {
1195   char *str = (char *)malloc(10 * sizeof(char));
1196   //void *str = malloc(10 * sizeof(char));
1197   memset(str, '\0', 10);
1198   clang_analyzer_eval(str[1] == 0);      // expected-warning{{TRUE}}
1199   clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
1200   free(str);
1201 }
1202 
1203 #ifdef SUPPRESS_OUT_OF_BOUND
1204 void memset5_char_malloc_overflow_null() {
1205   char *str = (char *)malloc(10 * sizeof(char));
1206   memset(str, '\0', 12);
1207   clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}}
1208   free(str);
1209 }
1210 #endif
1211 
1212 void memset6_char_array_nonnull() {
1213   char str[] = "abcd";
1214   clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
1215   memset(str, '0', 2);
1216   clang_analyzer_eval(str[0] == 'a');    // expected-warning{{UNKNOWN}}
1217   clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}}
1218 }
1219 
1220 #ifdef SUPPRESS_OUT_OF_BOUND
1221 void memset8_char_array_nonnull() {
1222   char str[5] = "abcd";
1223   clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
1224   memset(str, '0', 10);
1225   clang_analyzer_eval(str[0] != '0');     // expected-warning{{UNKNOWN}}
1226   clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
1227   clang_analyzer_eval(strlen(str) < 10);  // expected-warning{{FALSE}}
1228 }
1229 #endif
1230 
1231 struct POD_memset {
1232   int num;
1233   char c;
1234 };
1235 
1236 void memset10_struct() {
1237   struct POD_memset pod;
1238   char *str = (char *)&pod;
1239   pod.num = 1;
1240   pod.c = 1;
1241   clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}}
1242   memset(str, 0, sizeof(struct POD_memset));
1243   clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}}
1244 }
1245 
1246 #ifdef SUPPRESS_OUT_OF_BOUND
1247 void memset11_struct_field() {
1248   struct POD_memset pod;
1249   pod.num = 1;
1250   pod.c = '1';
1251   memset(&pod.num, 0, sizeof(struct POD_memset));
1252 
1253   clang_analyzer_eval(pod.num == 0);  // expected-warning{{TRUE}}
1254   clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}}
1255 }
1256 
1257 void memset12_struct_field() {
1258   struct POD_memset pod;
1259   pod.num = 1;
1260   pod.c = '1';
1261   memset(&pod.c, 0, sizeof(struct POD_memset));
1262   clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}}
1263   clang_analyzer_eval(pod.c == 0);   // expected-warning{{UNKNOWN}}
1264 }
1265 
1266 union U_memset {
1267   int i;
1268   double d;
1269   char c;
1270 };
1271 
1272 void memset13_union_field() {
1273   union U_memset u;
1274   u.i = 5;
1275   memset(&u.i, '\0', sizeof(union U_memset));
1276   // Note: This should be TRUE, analyzer can't handle union perfectly now.
1277   clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}}
1278 }
1279 #endif
1280 
1281 void memset14_region_cast() {
1282   char *str = (char *)malloc(10 * sizeof(int));
1283   int *array = (int *)str;
1284   memset(array, 0, 10 * sizeof(int));
1285   clang_analyzer_eval(str[10] == '\0');            // expected-warning{{TRUE}}
1286   clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}}
1287   clang_analyzer_eval(strlen(str) == 0);           // expected-warning{{TRUE}}
1288   free(str);
1289 }
1290 
1291 void memset15_region_cast() {
1292   char *str = (char *)malloc(10 * sizeof(int));
1293   int *array = (int *)str;
1294   memset(array, 0, 5 * sizeof(int));
1295   clang_analyzer_eval(str[10] == '\0');            // expected-warning{{UNKNOWN}}
1296   clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}}
1297   clang_analyzer_eval(strlen(str) == 0);           // expected-warning{{TRUE}}
1298   free(str);
1299 }
1300 
1301 int memset20_scalar() {
1302   int *x = malloc(sizeof(int));
1303   *x = 10;
1304   memset(x, 0, sizeof(int));
1305   int num = 1 / *x; // expected-warning{{Division by zero}}
1306   free(x);
1307   return num;
1308 }
1309 
1310 int memset21_scalar() {
1311   int *x = malloc(sizeof(int));
1312   memset(x, 0, 1);
1313   int num = 1 / *x;
1314   free(x);
1315   return num;
1316 }
1317 
1318 void memset22_array() {
1319   int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
1320   clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}}
1321   memset(array, 0, sizeof(array));
1322   clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}}
1323 }
1324 
1325 void memset23_array_pod_object() {
1326   struct POD_memset array[10];
1327   array[1].num = 10;
1328   array[1].c = 'c';
1329   clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}}
1330   memset(&array[1], 0, sizeof(struct POD_memset));
1331   clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}}
1332 }
1333 
1334 void memset24_array_pod_object() {
1335   struct POD_memset array[10];
1336   array[1].num = 10;
1337   array[1].c = 'c';
1338   clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}}
1339   memset(array, 0, sizeof(array));
1340   clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}}
1341 }
1342 
1343 void memset25_symbol(char c) {
1344   char array[10] = {1};
1345   if (c != 0)
1346     return;
1347 
1348   memset(array, c, 10);
1349 
1350   clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}}
1351   clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}}
1352 }
1353 
1354 void memset26_upper_UCHAR_MAX() {
1355   char array[10] = {1};
1356 
1357   memset(array, 1024, 10);
1358 
1359   clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}}
1360   clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}}
1361 }
1362 
1363 //===----------------------------------------------------------------------===
1364 // FIXMEs
1365 //===----------------------------------------------------------------------===
1366 
1367 // The analyzer_eval call below should evaluate to true. We are being too
1368 // aggressive in marking the (length of) src symbol dead. The length of dst
1369 // depends on src. This could be explicitly specified in the checker or the
1370 // logic for handling MetadataSymbol in SymbolManager needs to change.
1371 void strcat_symbolic_src_length(char *src) {
1372 	char dst[8] = "1234";
1373 	strcat(dst, src);
1374   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
1375 }
1376 
1377 
1378 // The analyzer_eval call below should evaluate to true. Most likely the same
1379 // issue as the test above.
1380 void strncpy_exactly_matching_buffer2(char *y) {
1381 	if (strlen(y) >= 4)
1382 		return;
1383 
1384 	char x[4];
1385 	strncpy(x, y, 4); // no-warning
1386 
1387 	// This time, we know that y fits in x anyway.
1388   clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
1389 }
1390 
1391 void memset7_char_array_nonnull() {
1392   char str[5] = "abcd";
1393   clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
1394   memset(str, '0', 5);
1395   // FIXME: This should be TRUE.
1396   clang_analyzer_eval(str[0] == '0');    // expected-warning{{UNKNOWN}}
1397   clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}}
1398 }
1399 
1400 void memset16_region_cast() {
1401   char *str = (char *)malloc(10 * sizeof(int));
1402   int *array = (int *)str;
1403   memset(array, '0', 10 * sizeof(int));
1404   // FIXME: This should be TRUE.
1405   clang_analyzer_eval(str[10] == '0');                            // expected-warning{{UNKNOWN}}
1406   clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}}
1407   clang_analyzer_eval(strlen(str) >= 10 * sizeof(int));           // expected-warning{{TRUE}}
1408   free(str);
1409 }
1410 
1411 #ifdef SUPPRESS_OUT_OF_BOUND
1412 void memset17_region_cast() {
1413   char *str = (char *)malloc(10 * sizeof(int));
1414   int *array = (int *)str;
1415   memset(array, '0', 12 * sizeof(int));
1416   clang_analyzer_eval(str[10] == '0');                            // expected-warning{{UNKNOWN}}
1417   clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}}
1418   clang_analyzer_eval(strlen(str) >= 12 * sizeof(int));           // expected-warning{{TRUE}}
1419   free(str);
1420 }
1421 
1422 void memset18_memset_multiple_times() {
1423   char *str = (char *)malloc(10 * sizeof(char));
1424   clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}}
1425 
1426   memset(str + 2, '\0', 10 * sizeof(char));
1427   clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}}
1428   clang_analyzer_eval(str[1] == '\0');   // expected-warning{{UNKNOWN}}
1429 
1430   memset(str, '0', 10 * sizeof(char));
1431   clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
1432   // FIXME: This should be TRUE.
1433   clang_analyzer_eval(str[1] == '0');     // expected-warning{{UNKNOWN}}
1434 
1435   free(str);
1436 }
1437 
1438 void memset19_memset_multiple_times() {
1439   char *str = (char *)malloc(10 * sizeof(char));
1440   clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}}
1441 
1442   memset(str, '0', 10 * sizeof(char));
1443   clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
1444   // FIXME: This should be TRUE.
1445   clang_analyzer_eval(str[1] == '0');     // expected-warning{{UNKNOWN}}
1446 
1447   memset(str + 2, '\0', 10 * sizeof(char));
1448   clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}}
1449   clang_analyzer_eval(str[1] == '0');     // expected-warning{{UNKNOWN}}
1450 
1451   free(str);
1452 }
1453 #endif
1454 
1455 // The analyzer does not support binding a symbol with default binding.
1456 void memset27_symbol(char c) {
1457   char array[10] = {0};
1458   if (c < 10)
1459     return;
1460 
1461   memset(array, c, 10);
1462 
1463   clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}}
1464   // FIXME: This should be TRUE.
1465   clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}}
1466 }
1467 
1468 void memset28() {
1469   short x;
1470   memset(&x, 1, sizeof(short));
1471   // This should be true.
1472   clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}}
1473 }
1474