blob: 89283befad213d4f605b632785ef63727b6d6f6b [file] [log] [blame]
Ted Kremenek033a07e2011-08-03 23:14:55 +00001// 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
Anna Zakse3d250e2011-12-11 18:43:40 +00004// 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
Jordy Rose19c5dd12010-07-27 01:37:31 +00005
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
Chris Lattnerfc8f0e12011-04-15 05:22:18 +000018// Functions that have variants and are also available as builtins should be
Jordy Rose19c5dd12010-07-27 01:37:31 +000019// 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
Jordy Rosee64f3112010-08-16 07:51:42 +000027#define NULL 0
Jordy Rose19c5dd12010-07-27 01:37:31 +000028typedef typeof(sizeof(int)) size_t;
Anna Zakse3d250e2011-12-11 18:43:40 +000029int scanf(const char *restrict format, ...);
Jordy Rose19c5dd12010-07-27 01:37:31 +000030
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)
Jordy Rosea5261542010-08-14 21:02:52 +000040 (void)*(char*)0; // no-warning
Jordy Rose19c5dd12010-07-27 01:37:31 +000041}
42
43void strlen_constant1() {
44 const char *a = "123";
45 if (strlen(a) != 3)
Jordy Rosea5261542010-08-14 21:02:52 +000046 (void)*(char*)0; // no-warning
Jordy Rose19c5dd12010-07-27 01:37:31 +000047}
48
49void strlen_constant2(char x) {
50 char a[] = "123";
Jordy Rosea5261542010-08-14 21:02:52 +000051 if (strlen(a) != 3)
52 (void)*(char*)0; // no-warning
Jordy Rose19c5dd12010-07-27 01:37:31 +000053 a[0] = x;
54 if (strlen(a) != 3)
55 (void)*(char*)0; // expected-warning{{null}}
56}
57
58size_t strlen_null() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +000059 return strlen(0); // expected-warning{{Null pointer argument in call to string length function}}
Jordy Rose19c5dd12010-07-27 01:37:31 +000060}
61
62size_t strlen_fn() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +000063 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}}
Jordy Rose19c5dd12010-07-27 01:37:31 +000064}
65
66size_t strlen_nonloc() {
67label:
Jordy Rose9e49d9f2011-06-20 02:06:40 +000068 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}}
Jordy Rose19c5dd12010-07-27 01:37:31 +000069}
Jordy Rosea5261542010-08-14 21:02:52 +000070
71void strlen_subregion() {
Carl Norume224ba72011-03-07 22:57:45 +000072 struct two_strings { char a[2], b[2]; };
Jordy Rosea5261542010-08-14 21:02:52 +000073 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_liveness(const char *x) {
137 if (strlen(x) < 5)
138 return;
139 if (strlen(x) < 5)
140 (void)*(char*)0; // no-warning
141}
Jordy Rosee64f3112010-08-16 07:51:42 +0000142
143//===----------------------------------------------------------------------===
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000144// strnlen()
145//===----------------------------------------------------------------------===
146
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000147size_t strnlen(const char *s, size_t maxlen);
148
149void strnlen_constant0() {
150 if (strnlen("123", 10) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000151 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000152}
153
154void strnlen_constant1() {
155 const char *a = "123";
156 if (strnlen(a, 10) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000157 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000158}
159
160void strnlen_constant2(char x) {
161 char a[] = "123";
162 if (strnlen(a, 10) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000163 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000164 a[0] = x;
165 if (strnlen(a, 10) != 3)
166 (void)*(char*)0; // expected-warning{{null}}
167}
168
169void strnlen_constant4() {
170 if (strnlen("123456", 3) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000171 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000172}
173
174void strnlen_constant5() {
175 const char *a = "123456";
176 if (strnlen(a, 3) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000177 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000178}
179
180void strnlen_constant6(char x) {
181 char a[] = "123456";
182 if (strnlen(a, 3) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000183 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000184 a[0] = x;
185 if (strnlen(a, 3) != 3)
186 (void)*(char*)0; // expected-warning{{null}}
187}
188
189size_t strnlen_null() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000190 return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000191}
192
193size_t strnlen_fn() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000194 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}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000195}
196
197size_t strnlen_nonloc() {
198label:
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000199 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}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000200}
201
Jordy Rose793bff32011-06-14 01:15:31 +0000202void strnlen_zero() {
203 if (strnlen("abc", 0) != 0)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000204 (void)*(char*)0; // expected-warning{{never executed}}
Jordy Rose793bff32011-06-14 01:15:31 +0000205 if (strnlen(NULL, 0) != 0) // no-warning
206 (void)*(char*)0; // no-warning
207}
208
209size_t strnlen_compound_literal() {
210 // This used to crash because we don't model the string lengths of
211 // compound literals.
212 return strnlen((char[]) { 'a', 'b', 0 }, 1);
213}
214
215size_t strnlen_unknown_limit(float f) {
216 // This used to crash because we don't model the integer values of floats.
217 return strnlen("abc", (int)f);
218}
219
220void strnlen_is_not_strlen(char *x) {
221 if (strnlen(x, 10) != strlen(x))
222 (void)*(char*)0; // expected-warning{{null}}
223}
224
225void strnlen_at_limit(char *x) {
226 size_t len = strnlen(x, 10);
227 if (len > 10)
228 (void)*(char*)0; // expected-warning{{never executed}}
229 if (len == 10)
230 (void)*(char*)0; // expected-warning{{null}}
231}
232
233void strnlen_less_than_limit(char *x) {
234 size_t len = strnlen(x, 10);
235 if (len > 10)
236 (void)*(char*)0; // expected-warning{{never executed}}
237 if (len < 10)
238 (void)*(char*)0; // expected-warning{{null}}
239}
240
241void strnlen_at_actual(size_t limit) {
242 size_t len = strnlen("abc", limit);
243 if (len > 3)
244 (void)*(char*)0; // expected-warning{{never executed}}
245 if (len == 3)
246 (void)*(char*)0; // expected-warning{{null}}
247}
248
249void strnlen_less_than_actual(size_t limit) {
250 size_t len = strnlen("abc", limit);
251 if (len > 3)
252 (void)*(char*)0; // expected-warning{{never executed}}
253 if (len < 3)
254 (void)*(char*)0; // expected-warning{{null}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000255}
256
257//===----------------------------------------------------------------------===
Jordy Rosee64f3112010-08-16 07:51:42 +0000258// strcpy()
259//===----------------------------------------------------------------------===
260
261#ifdef VARIANT
262
263#define __strcpy_chk BUILTIN(__strcpy_chk)
264char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
265
266#define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
267
268#else /* VARIANT */
269
270#define strcpy BUILTIN(strcpy)
271char *strcpy(char *restrict s1, const char *restrict s2);
272
273#endif /* VARIANT */
274
275
276void strcpy_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000277 strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000278}
279
280void strcpy_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000281 strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000282}
283
284void strcpy_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000285 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}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000286}
287
288void strcpy_effects(char *x, char *y) {
289 char a = x[0];
290
291 if (strcpy(x, y) != x)
292 (void)*(char*)0; // no-warning
293
294 if (strlen(x) != strlen(y))
295 (void)*(char*)0; // no-warning
296
297 if (a != x[0])
298 (void)*(char*)0; // expected-warning{{null}}
299}
300
301void strcpy_overflow(char *y) {
302 char x[4];
303 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000304 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000305}
306
307void strcpy_no_overflow(char *y) {
308 char x[4];
309 if (strlen(y) == 3)
310 strcpy(x, y); // no-warning
311}
312
313//===----------------------------------------------------------------------===
314// stpcpy()
315//===----------------------------------------------------------------------===
316
317#ifdef VARIANT
318
319#define __stpcpy_chk BUILTIN(__stpcpy_chk)
320char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
321
322#define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
323
324#else /* VARIANT */
325
326#define stpcpy BUILTIN(stpcpy)
327char *stpcpy(char *restrict s1, const char *restrict s2);
328
329#endif /* VARIANT */
330
331
332void stpcpy_effect(char *x, char *y) {
333 char a = x[0];
334
335 if (stpcpy(x, y) != &x[strlen(y)])
336 (void)*(char*)0; // no-warning
337
338 if (strlen(x) != strlen(y))
339 (void)*(char*)0; // no-warning
340
341 if (a != x[0])
342 (void)*(char*)0; // expected-warning{{null}}
343}
344
345void stpcpy_overflow(char *y) {
346 char x[4];
347 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000348 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000349}
350
351void stpcpy_no_overflow(char *y) {
352 char x[4];
353 if (strlen(y) == 3)
354 stpcpy(x, y); // no-warning
355}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000356
357//===----------------------------------------------------------------------===
358// strcat()
359//===----------------------------------------------------------------------===
360
361#ifdef VARIANT
362
363#define __strcat_chk BUILTIN(__strcat_chk)
364char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
365
366#define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
367
368#else /* VARIANT */
369
370#define strcat BUILTIN(strcat)
371char *strcat(char *restrict s1, const char *restrict s2);
372
373#endif /* VARIANT */
374
375
376void strcat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000377 strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000378}
379
380void strcat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000381 strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000382}
383
384void strcat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000385 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}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000386}
387
388void strcat_effects(char *y) {
389 char x[8] = "123";
390 size_t orig_len = strlen(x);
391 char a = x[0];
392
393 if (strlen(y) != 4)
394 return;
395
396 if (strcat(x, y) != x)
397 (void)*(char*)0; // no-warning
398
399 if ((int)strlen(x) != (orig_len + strlen(y)))
400 (void)*(char*)0; // no-warning
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000401}
402
403void strcat_overflow_0(char *y) {
404 char x[4] = "12";
405 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000406 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000407}
408
409void strcat_overflow_1(char *y) {
410 char x[4] = "12";
411 if (strlen(y) == 3)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000412 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000413}
414
415void strcat_overflow_2(char *y) {
416 char x[4] = "12";
417 if (strlen(y) == 2)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000418 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000419}
420
421void strcat_no_overflow(char *y) {
422 char x[5] = "12";
423 if (strlen(y) == 2)
424 strcat(x, y); // no-warning
425}
426
Jordy Rosed5af0e12011-06-15 05:52:56 +0000427void strcat_symbolic_dst_length(char *dst) {
428 strcat(dst, "1234");
429 if (strlen(dst) < 4)
430 (void)*(char*)0; // no-warning
431}
432
433void strcat_symbolic_src_length(char *src) {
434 char dst[8] = "1234";
435 strcat(dst, src);
436 if (strlen(dst) < 4)
437 (void)*(char*)0; // no-warning
438}
439
Anna Zakse3d250e2011-12-11 18:43:40 +0000440void strcat_symbolic_dst_length_taint(char *dst) {
441 scanf("%s", dst); // Taint data.
442 strcat(dst, "1234");
443 if (strlen(dst) < 4)
444 (void)*(char*)0; // no-warning
445}
446
Jordy Rosed5af0e12011-06-15 05:52:56 +0000447void strcat_unknown_src_length(char *src, int offset) {
448 char dst[8] = "1234";
449 strcat(dst, &src[offset]);
450 if (strlen(dst) < 4)
451 (void)*(char*)0; // no-warning
452}
453
454// There is no strcat_unknown_dst_length because if we can't get a symbolic
455// length for the "before" strlen, we won't be able to set one for "after".
456
457void strcat_too_big(char *dst, char *src) {
458 if (strlen(dst) != (((size_t)0) - 2))
459 return;
460 if (strlen(src) != 2)
461 return;
462 strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
463}
464
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000465
466//===----------------------------------------------------------------------===
Jordy Rose5e5f1502011-06-20 03:49:16 +0000467// strncpy()
468//===----------------------------------------------------------------------===
469
470#ifdef VARIANT
471
472#define __strncpy_chk BUILTIN(__strncpy_chk)
473char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
474
475#define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
476
477#else /* VARIANT */
478
479#define strncpy BUILTIN(strncpy)
480char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
481
482#endif /* VARIANT */
483
484
485void strncpy_null_dst(char *x) {
486 strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
487}
488
489void strncpy_null_src(char *x) {
490 strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
491}
492
493void strncpy_fn(char *x) {
494 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}}
495}
496
497void strncpy_effects(char *x, char *y) {
498 char a = x[0];
499
500 if (strncpy(x, y, 5) != x)
501 (void)*(char*)0; // no-warning
502
503 if (strlen(x) != strlen(y))
504 (void)*(char*)0; // expected-warning{{null}}
505
506 if (a != x[0])
507 (void)*(char*)0; // expected-warning{{null}}
508}
509
510void strncpy_overflow(char *y) {
511 char x[4];
512 if (strlen(y) == 4)
513 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
514}
515
516void strncpy_no_overflow(char *y) {
517 char x[4];
518 if (strlen(y) == 3)
519 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
520}
521
522void strncpy_no_overflow2(char *y, int n) {
523 if (n <= 4)
524 return;
525
526 char x[4];
527 if (strlen(y) == 3)
528 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
529}
530
531void strncpy_truncate(char *y) {
532 char x[4];
533 if (strlen(y) == 4)
534 strncpy(x, y, 3); // no-warning
535}
536
537void strncpy_no_truncate(char *y) {
538 char x[4];
539 if (strlen(y) == 3)
540 strncpy(x, y, 3); // no-warning
541}
542
543void strncpy_exactly_matching_buffer(char *y) {
544 char x[4];
545 strncpy(x, y, 4); // no-warning
546
547 // strncpy does not null-terminate, so we have no idea what the strlen is
548 // after this.
549 if (strlen(x) > 4)
550 (void)*(int*)0; // expected-warning{{null}}
551}
552
553void strncpy_exactly_matching_buffer2(char *y) {
554 if (strlen(y) >= 4)
555 return;
556
557 char x[4];
558 strncpy(x, y, 4); // no-warning
559
560 // This time, we know that y fits in x anyway.
561 if (strlen(x) > 3)
562 (void)*(int*)0; // no-warning
563}
564
565//===----------------------------------------------------------------------===
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000566// strncat()
567//===----------------------------------------------------------------------===
568
569#ifdef VARIANT
570
571#define __strncat_chk BUILTIN(__strncat_chk)
572char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
573
574#define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
575
576#else /* VARIANT */
577
578#define strncat BUILTIN(strncat)
579char *strncat(char *restrict s1, const char *restrict s2, size_t n);
580
581#endif /* VARIANT */
582
583
584void strncat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000585 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000586}
587
588void strncat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000589 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000590}
591
592void strncat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000593 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}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000594}
595
596void strncat_effects(char *y) {
597 char x[8] = "123";
598 size_t orig_len = strlen(x);
599 char a = x[0];
600
601 if (strlen(y) != 4)
602 return;
603
604 if (strncat(x, y, strlen(y)) != x)
605 (void)*(char*)0; // no-warning
606
607 if (strlen(x) != orig_len + strlen(y))
608 (void)*(char*)0; // no-warning
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000609}
610
611void strncat_overflow_0(char *y) {
612 char x[4] = "12";
613 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000614 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000615}
616
617void strncat_overflow_1(char *y) {
618 char x[4] = "12";
619 if (strlen(y) == 3)
Jordy Rose8912aae2011-06-20 21:55:40 +0000620 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000621}
622
623void strncat_overflow_2(char *y) {
624 char x[4] = "12";
625 if (strlen(y) == 2)
Jordy Rose8912aae2011-06-20 21:55:40 +0000626 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000627}
628
629void strncat_overflow_3(char *y) {
630 char x[4] = "12";
631 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000632 strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000633}
634void strncat_no_overflow_1(char *y) {
635 char x[5] = "12";
636 if (strlen(y) == 2)
637 strncat(x, y, strlen(y)); // no-warning
638}
639
640void strncat_no_overflow_2(char *y) {
641 char x[4] = "12";
642 if (strlen(y) == 4)
643 strncat(x, y, 1); // no-warning
644}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000645
Jordy Rose8912aae2011-06-20 21:55:40 +0000646void strncat_symbolic_dst_length(char *dst) {
647 strncat(dst, "1234", 5);
648 if (strlen(dst) < 4)
649 (void)*(char*)0; // no-warning
650}
651
652void strncat_symbolic_src_length(char *src) {
653 char dst[8] = "1234";
654 strncat(dst, src, 3);
655 if (strlen(dst) < 4)
656 (void)*(char*)0; // no-warning
657
658 char dst2[8] = "1234";
659 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
660}
661
662void strncat_unknown_src_length(char *src, int offset) {
663 char dst[8] = "1234";
664 strncat(dst, &src[offset], 3);
665 if (strlen(dst) < 4)
666 (void)*(char*)0; // no-warning
667
668 char dst2[8] = "1234";
669 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
670}
671
672// There is no strncat_unknown_dst_length because if we can't get a symbolic
673// length for the "before" strlen, we won't be able to set one for "after".
674
675void strncat_symbolic_limit(unsigned limit) {
676 char dst[6] = "1234";
677 char src[] = "567";
678 strncat(dst, src, limit); // no-warning
679 if (strlen(dst) < 4)
680 (void)*(char*)0; // no-warning
681 if (strlen(dst) == 4)
682 (void)*(char*)0; // expected-warning{{null}}
683}
684
685void strncat_unknown_limit(float limit) {
686 char dst[6] = "1234";
687 char src[] = "567";
688 strncat(dst, src, (size_t)limit); // no-warning
689 if (strlen(dst) < 4)
690 (void)*(char*)0; // no-warning
691 if (strlen(dst) == 4)
692 (void)*(char*)0; // expected-warning{{null}}
693}
694
695void strncat_too_big(char *dst, char *src) {
696 if (strlen(dst) != (((size_t)0) - 2))
697 return;
698 if (strlen(src) != 2)
699 return;
700 strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
701}
702
Lenny Maiorani318dd922011-04-12 17:08:43 +0000703//===----------------------------------------------------------------------===
704// strcmp()
705//===----------------------------------------------------------------------===
706
707#define strcmp BUILTIN(strcmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000708int strcmp(const char * s1, const char * s2);
Lenny Maiorani318dd922011-04-12 17:08:43 +0000709
710void strcmp_constant0() {
711 if (strcmp("123", "123") != 0)
712 (void)*(char*)0; // no-warning
713}
714
715void strcmp_constant_and_var_0() {
716 char *x = "123";
717 if (strcmp(x, "123") != 0)
718 (void)*(char*)0; // no-warning
719}
720
721void strcmp_constant_and_var_1() {
722 char *x = "123";
723 if (strcmp("123", x) != 0)
724 (void)*(char*)0; // no-warning
725}
726
727void strcmp_0() {
728 char *x = "123";
729 char *y = "123";
730 if (strcmp(x, y) != 0)
731 (void)*(char*)0; // no-warning
732}
733
734void strcmp_1() {
735 char *x = "234";
736 char *y = "123";
737 if (strcmp(x, y) != 1)
738 (void)*(char*)0; // no-warning
739}
740
741void strcmp_2() {
742 char *x = "123";
743 char *y = "234";
744 if (strcmp(x, y) != -1)
745 (void)*(char*)0; // no-warning
746}
747
748void strcmp_null_0() {
749 char *x = NULL;
750 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000751 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000752}
753
754void strcmp_null_1() {
755 char *x = "123";
756 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000757 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000758}
759
760void strcmp_diff_length_0() {
761 char *x = "12345";
762 char *y = "234";
763 if (strcmp(x, y) != -1)
764 (void)*(char*)0; // no-warning
765}
766
767void strcmp_diff_length_1() {
768 char *x = "123";
769 char *y = "23456";
770 if (strcmp(x, y) != -1)
771 (void)*(char*)0; // no-warning
772}
773
774void strcmp_diff_length_2() {
775 char *x = "12345";
776 char *y = "123";
777 if (strcmp(x, y) != 1)
778 (void)*(char*)0; // no-warning
779}
780
781void strcmp_diff_length_3() {
782 char *x = "123";
783 char *y = "12345";
784 if (strcmp(x, y) != -1)
785 (void)*(char*)0; // no-warning
786}
787
Jordy Roseadc42d42011-06-16 07:13:34 +0000788void strcmp_embedded_null () {
789 if (strcmp("\0z", "\0y") != 0)
790 (void)*(char*)0; // no-warning
791}
792
793void strcmp_unknown_arg (char *unknown) {
794 if (strcmp(unknown, unknown) != 0)
795 (void)*(char*)0; // no-warning
796}
797
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000798//===----------------------------------------------------------------------===
799// strncmp()
800//===----------------------------------------------------------------------===
801
802#define strncmp BUILTIN(strncmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000803int strncmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000804
805void strncmp_constant0() {
806 if (strncmp("123", "123", 3) != 0)
807 (void)*(char*)0; // no-warning
808}
809
810void strncmp_constant_and_var_0() {
811 char *x = "123";
812 if (strncmp(x, "123", 3) != 0)
813 (void)*(char*)0; // no-warning
814}
815
816void strncmp_constant_and_var_1() {
817 char *x = "123";
818 if (strncmp("123", x, 3) != 0)
819 (void)*(char*)0; // no-warning
820}
821
822void strncmp_0() {
823 char *x = "123";
824 char *y = "123";
825 if (strncmp(x, y, 3) != 0)
826 (void)*(char*)0; // no-warning
827}
828
829void strncmp_1() {
830 char *x = "234";
831 char *y = "123";
832 if (strncmp(x, y, 3) != 1)
833 (void)*(char*)0; // no-warning
834}
835
836void strncmp_2() {
837 char *x = "123";
838 char *y = "234";
839 if (strncmp(x, y, 3) != -1)
840 (void)*(char*)0; // no-warning
841}
842
843void strncmp_null_0() {
844 char *x = NULL;
845 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000846 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000847}
848
849void strncmp_null_1() {
850 char *x = "123";
851 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000852 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000853}
854
855void strncmp_diff_length_0() {
856 char *x = "12345";
857 char *y = "234";
858 if (strncmp(x, y, 5) != -1)
859 (void)*(char*)0; // no-warning
860}
861
862void strncmp_diff_length_1() {
863 char *x = "123";
864 char *y = "23456";
865 if (strncmp(x, y, 5) != -1)
866 (void)*(char*)0; // no-warning
867}
868
869void strncmp_diff_length_2() {
870 char *x = "12345";
871 char *y = "123";
872 if (strncmp(x, y, 5) != 1)
873 (void)*(char*)0; // no-warning
874}
875
876void strncmp_diff_length_3() {
877 char *x = "123";
878 char *y = "12345";
879 if (strncmp(x, y, 5) != -1)
880 (void)*(char*)0; // no-warning
881}
882
883void strncmp_diff_length_4() {
884 char *x = "123";
885 char *y = "12345";
886 if (strncmp(x, y, 3) != 0)
887 (void)*(char*)0; // no-warning
888}
889
890void strncmp_diff_length_5() {
891 char *x = "012";
892 char *y = "12345";
893 if (strncmp(x, y, 3) != -1)
894 (void)*(char*)0; // no-warning
895}
896
897void strncmp_diff_length_6() {
898 char *x = "234";
899 char *y = "12345";
900 if (strncmp(x, y, 3) != 1)
901 (void)*(char*)0; // no-warning
902}
903
Jordy Roseadc42d42011-06-16 07:13:34 +0000904void strncmp_embedded_null () {
905 if (strncmp("ab\0zz", "ab\0yy", 4) != 0)
906 (void)*(char*)0; // no-warning
907}
908
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000909//===----------------------------------------------------------------------===
910// strcasecmp()
911//===----------------------------------------------------------------------===
912
913#define strcasecmp BUILTIN(strcasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000914int strcasecmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000915
916void strcasecmp_constant0() {
917 if (strcasecmp("abc", "Abc") != 0)
918 (void)*(char*)0; // no-warning
919}
920
921void strcasecmp_constant_and_var_0() {
922 char *x = "abc";
923 if (strcasecmp(x, "Abc") != 0)
924 (void)*(char*)0; // no-warning
925}
926
927void strcasecmp_constant_and_var_1() {
928 char *x = "abc";
929 if (strcasecmp("Abc", x) != 0)
930 (void)*(char*)0; // no-warning
931}
932
933void strcasecmp_0() {
934 char *x = "abc";
935 char *y = "Abc";
936 if (strcasecmp(x, y) != 0)
937 (void)*(char*)0; // no-warning
938}
939
940void strcasecmp_1() {
941 char *x = "Bcd";
942 char *y = "abc";
943 if (strcasecmp(x, y) != 1)
944 (void)*(char*)0; // no-warning
945}
946
947void strcasecmp_2() {
948 char *x = "abc";
949 char *y = "Bcd";
950 if (strcasecmp(x, y) != -1)
951 (void)*(char*)0; // no-warning
952}
953
954void strcasecmp_null_0() {
955 char *x = NULL;
956 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000957 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000958}
959
960void strcasecmp_null_1() {
961 char *x = "123";
962 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000963 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000964}
965
966void strcasecmp_diff_length_0() {
967 char *x = "abcde";
968 char *y = "aBd";
969 if (strcasecmp(x, y) != -1)
970 (void)*(char*)0; // no-warning
971}
972
973void strcasecmp_diff_length_1() {
974 char *x = "abc";
975 char *y = "aBdef";
976 if (strcasecmp(x, y) != -1)
977 (void)*(char*)0; // no-warning
978}
979
980void strcasecmp_diff_length_2() {
981 char *x = "aBcDe";
982 char *y = "abc";
983 if (strcasecmp(x, y) != 1)
984 (void)*(char*)0; // no-warning
985}
986
987void strcasecmp_diff_length_3() {
988 char *x = "aBc";
989 char *y = "abcde";
990 if (strcasecmp(x, y) != -1)
991 (void)*(char*)0; // no-warning
992}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000993
Jordy Roseadc42d42011-06-16 07:13:34 +0000994void strcasecmp_embedded_null () {
995 if (strcasecmp("ab\0zz", "ab\0yy") != 0)
996 (void)*(char*)0; // no-warning
997}
998
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000999//===----------------------------------------------------------------------===
1000// strncasecmp()
1001//===----------------------------------------------------------------------===
1002
1003#define strncasecmp BUILTIN(strncasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +00001004int strncasecmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001005
1006void strncasecmp_constant0() {
1007 if (strncasecmp("abc", "Abc", 3) != 0)
1008 (void)*(char*)0; // no-warning
1009}
1010
1011void strncasecmp_constant_and_var_0() {
1012 char *x = "abc";
1013 if (strncasecmp(x, "Abc", 3) != 0)
1014 (void)*(char*)0; // no-warning
1015}
1016
1017void strncasecmp_constant_and_var_1() {
1018 char *x = "abc";
1019 if (strncasecmp("Abc", x, 3) != 0)
1020 (void)*(char*)0; // no-warning
1021}
1022
1023void strncasecmp_0() {
1024 char *x = "abc";
1025 char *y = "Abc";
1026 if (strncasecmp(x, y, 3) != 0)
1027 (void)*(char*)0; // no-warning
1028}
1029
1030void strncasecmp_1() {
1031 char *x = "Bcd";
1032 char *y = "abc";
1033 if (strncasecmp(x, y, 3) != 1)
1034 (void)*(char*)0; // no-warning
1035}
1036
1037void strncasecmp_2() {
1038 char *x = "abc";
1039 char *y = "Bcd";
1040 if (strncasecmp(x, y, 3) != -1)
1041 (void)*(char*)0; // no-warning
1042}
1043
1044void strncasecmp_null_0() {
1045 char *x = NULL;
1046 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001047 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001048}
1049
1050void strncasecmp_null_1() {
1051 char *x = "123";
1052 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001053 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001054}
1055
1056void strncasecmp_diff_length_0() {
1057 char *x = "abcde";
1058 char *y = "aBd";
1059 if (strncasecmp(x, y, 5) != -1)
1060 (void)*(char*)0; // no-warning
1061}
1062
1063void strncasecmp_diff_length_1() {
1064 char *x = "abc";
1065 char *y = "aBdef";
1066 if (strncasecmp(x, y, 5) != -1)
1067 (void)*(char*)0; // no-warning
1068}
1069
1070void strncasecmp_diff_length_2() {
1071 char *x = "aBcDe";
1072 char *y = "abc";
1073 if (strncasecmp(x, y, 5) != 1)
1074 (void)*(char*)0; // no-warning
1075}
1076
1077void strncasecmp_diff_length_3() {
1078 char *x = "aBc";
1079 char *y = "abcde";
1080 if (strncasecmp(x, y, 5) != -1)
1081 (void)*(char*)0; // no-warning
1082}
1083
1084void strncasecmp_diff_length_4() {
1085 char *x = "abcde";
1086 char *y = "aBc";
1087 if (strncasecmp(x, y, 3) != 0)
1088 (void)*(char*)0; // no-warning
1089}
1090
1091void strncasecmp_diff_length_5() {
1092 char *x = "abcde";
1093 char *y = "aBd";
1094 if (strncasecmp(x, y, 3) != -1)
1095 (void)*(char*)0; // no-warning
1096}
1097
1098void strncasecmp_diff_length_6() {
1099 char *x = "aBDe";
1100 char *y = "abc";
1101 if (strncasecmp(x, y, 3) != 1)
1102 (void)*(char*)0; // no-warning
1103}
Jordy Roseadc42d42011-06-16 07:13:34 +00001104
1105void strncasecmp_embedded_null () {
1106 if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0)
1107 (void)*(char*)0; // no-warning
1108}