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