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