blob: dc38681b35b28b170cb41828fee26fc8a64a525b [file] [log] [blame]
Anna Zaksbb2a6862012-02-20 21:10:37 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,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,unix.cstring,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
Anna Zaks2cbe7912011-12-20 22:35:30 +0000136void 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
Jordy Rosea5261542010-08-14 21:02:52 +0000148void strlen_liveness(const char *x) {
149 if (strlen(x) < 5)
150 return;
151 if (strlen(x) < 5)
152 (void)*(char*)0; // no-warning
153}
Jordy Rosee64f3112010-08-16 07:51:42 +0000154
155//===----------------------------------------------------------------------===
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000156// strnlen()
157//===----------------------------------------------------------------------===
158
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000159size_t strnlen(const char *s, size_t maxlen);
160
161void strnlen_constant0() {
162 if (strnlen("123", 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}
165
166void strnlen_constant1() {
167 const char *a = "123";
168 if (strnlen(a, 10) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000169 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000170}
171
172void strnlen_constant2(char x) {
173 char a[] = "123";
174 if (strnlen(a, 10) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000175 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000176 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)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000183 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000184}
185
186void strnlen_constant5() {
187 const char *a = "123456";
188 if (strnlen(a, 3) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000189 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000190}
191
192void strnlen_constant6(char x) {
193 char a[] = "123456";
194 if (strnlen(a, 3) != 3)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000195 (void)*(char*)0; // expected-warning{{never executed}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000196 a[0] = x;
197 if (strnlen(a, 3) != 3)
198 (void)*(char*)0; // expected-warning{{null}}
199}
200
201size_t strnlen_null() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000202 return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000203}
204
205size_t strnlen_fn() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000206 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 +0000207}
208
209size_t strnlen_nonloc() {
210label:
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000211 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 +0000212}
213
Jordy Rose793bff32011-06-14 01:15:31 +0000214void strnlen_zero() {
215 if (strnlen("abc", 0) != 0)
Jordy Rose0fa6bf72011-06-28 05:34:40 +0000216 (void)*(char*)0; // expected-warning{{never executed}}
Jordy Rose793bff32011-06-14 01:15:31 +0000217 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}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000267}
268
269//===----------------------------------------------------------------------===
Jordy Rosee64f3112010-08-16 07:51:42 +0000270// 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) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000289 strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000290}
291
292void strcpy_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000293 strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000294}
295
296void strcpy_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000297 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 +0000298}
299
Anna Zaksce8ef162012-01-13 00:56:48 +0000300void strcpy_fn_const(char *x) {
301 strcpy(x, (const char*)&strcpy_fn); // expected-warning{{Argument to string copy function is the address of the function 'strcpy_fn', which is not a null-terminated string}}
302}
303
Jordy Rosee64f3112010-08-16 07:51:42 +0000304void strcpy_effects(char *x, char *y) {
305 char a = x[0];
306
307 if (strcpy(x, y) != x)
308 (void)*(char*)0; // no-warning
309
310 if (strlen(x) != strlen(y))
311 (void)*(char*)0; // no-warning
312
313 if (a != x[0])
314 (void)*(char*)0; // expected-warning{{null}}
315}
316
317void strcpy_overflow(char *y) {
318 char x[4];
319 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000320 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000321}
322
323void strcpy_no_overflow(char *y) {
324 char x[4];
325 if (strlen(y) == 3)
326 strcpy(x, y); // no-warning
327}
328
329//===----------------------------------------------------------------------===
330// stpcpy()
331//===----------------------------------------------------------------------===
332
333#ifdef VARIANT
334
335#define __stpcpy_chk BUILTIN(__stpcpy_chk)
336char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
337
338#define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
339
340#else /* VARIANT */
341
342#define stpcpy BUILTIN(stpcpy)
343char *stpcpy(char *restrict s1, const char *restrict s2);
344
345#endif /* VARIANT */
346
347
348void stpcpy_effect(char *x, char *y) {
349 char a = x[0];
350
351 if (stpcpy(x, y) != &x[strlen(y)])
352 (void)*(char*)0; // no-warning
353
354 if (strlen(x) != strlen(y))
355 (void)*(char*)0; // no-warning
356
357 if (a != x[0])
358 (void)*(char*)0; // expected-warning{{null}}
359}
360
361void stpcpy_overflow(char *y) {
362 char x[4];
363 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000364 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000365}
366
367void stpcpy_no_overflow(char *y) {
368 char x[4];
369 if (strlen(y) == 3)
370 stpcpy(x, y); // no-warning
371}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000372
373//===----------------------------------------------------------------------===
374// strcat()
375//===----------------------------------------------------------------------===
376
377#ifdef VARIANT
378
379#define __strcat_chk BUILTIN(__strcat_chk)
380char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
381
382#define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
383
384#else /* VARIANT */
385
386#define strcat BUILTIN(strcat)
387char *strcat(char *restrict s1, const char *restrict s2);
388
389#endif /* VARIANT */
390
391
392void strcat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000393 strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000394}
395
396void strcat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000397 strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000398}
399
400void strcat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000401 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 +0000402}
403
404void strcat_effects(char *y) {
405 char x[8] = "123";
406 size_t orig_len = strlen(x);
407 char a = x[0];
408
409 if (strlen(y) != 4)
410 return;
411
412 if (strcat(x, y) != x)
413 (void)*(char*)0; // no-warning
414
415 if ((int)strlen(x) != (orig_len + strlen(y)))
416 (void)*(char*)0; // no-warning
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000417}
418
419void strcat_overflow_0(char *y) {
420 char x[4] = "12";
421 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000422 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000423}
424
425void strcat_overflow_1(char *y) {
426 char x[4] = "12";
427 if (strlen(y) == 3)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000428 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000429}
430
431void strcat_overflow_2(char *y) {
432 char x[4] = "12";
433 if (strlen(y) == 2)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000434 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000435}
436
437void strcat_no_overflow(char *y) {
438 char x[5] = "12";
439 if (strlen(y) == 2)
440 strcat(x, y); // no-warning
441}
442
Jordy Rosed5af0e12011-06-15 05:52:56 +0000443void strcat_symbolic_dst_length(char *dst) {
444 strcat(dst, "1234");
445 if (strlen(dst) < 4)
446 (void)*(char*)0; // no-warning
447}
448
449void strcat_symbolic_src_length(char *src) {
450 char dst[8] = "1234";
451 strcat(dst, src);
452 if (strlen(dst) < 4)
453 (void)*(char*)0; // no-warning
454}
455
Anna Zakse3d250e2011-12-11 18:43:40 +0000456void strcat_symbolic_dst_length_taint(char *dst) {
457 scanf("%s", dst); // Taint data.
458 strcat(dst, "1234");
459 if (strlen(dst) < 4)
460 (void)*(char*)0; // no-warning
461}
462
Jordy Rosed5af0e12011-06-15 05:52:56 +0000463void strcat_unknown_src_length(char *src, int offset) {
464 char dst[8] = "1234";
465 strcat(dst, &src[offset]);
466 if (strlen(dst) < 4)
467 (void)*(char*)0; // no-warning
468}
469
470// There is no strcat_unknown_dst_length because if we can't get a symbolic
471// length for the "before" strlen, we won't be able to set one for "after".
472
473void strcat_too_big(char *dst, char *src) {
474 if (strlen(dst) != (((size_t)0) - 2))
475 return;
476 if (strlen(src) != 2)
477 return;
478 strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
479}
480
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000481
482//===----------------------------------------------------------------------===
Jordy Rose5e5f1502011-06-20 03:49:16 +0000483// strncpy()
484//===----------------------------------------------------------------------===
485
486#ifdef VARIANT
487
488#define __strncpy_chk BUILTIN(__strncpy_chk)
489char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
490
491#define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
492
493#else /* VARIANT */
494
495#define strncpy BUILTIN(strncpy)
496char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
497
498#endif /* VARIANT */
499
500
501void strncpy_null_dst(char *x) {
502 strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
503}
504
505void strncpy_null_src(char *x) {
506 strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
507}
508
509void strncpy_fn(char *x) {
510 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}}
511}
512
513void strncpy_effects(char *x, char *y) {
514 char a = x[0];
515
516 if (strncpy(x, y, 5) != x)
517 (void)*(char*)0; // no-warning
518
519 if (strlen(x) != strlen(y))
520 (void)*(char*)0; // expected-warning{{null}}
521
522 if (a != x[0])
523 (void)*(char*)0; // expected-warning{{null}}
524}
525
526void strncpy_overflow(char *y) {
527 char x[4];
528 if (strlen(y) == 4)
529 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
530}
531
532void strncpy_no_overflow(char *y) {
533 char x[4];
534 if (strlen(y) == 3)
535 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
536}
537
538void strncpy_no_overflow2(char *y, int n) {
539 if (n <= 4)
540 return;
541
542 char x[4];
543 if (strlen(y) == 3)
544 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
545}
546
547void strncpy_truncate(char *y) {
548 char x[4];
549 if (strlen(y) == 4)
550 strncpy(x, y, 3); // no-warning
551}
552
553void strncpy_no_truncate(char *y) {
554 char x[4];
555 if (strlen(y) == 3)
556 strncpy(x, y, 3); // no-warning
557}
558
559void strncpy_exactly_matching_buffer(char *y) {
560 char x[4];
561 strncpy(x, y, 4); // no-warning
562
563 // strncpy does not null-terminate, so we have no idea what the strlen is
564 // after this.
565 if (strlen(x) > 4)
566 (void)*(int*)0; // expected-warning{{null}}
567}
568
569void strncpy_exactly_matching_buffer2(char *y) {
570 if (strlen(y) >= 4)
571 return;
572
573 char x[4];
574 strncpy(x, y, 4); // no-warning
575
576 // This time, we know that y fits in x anyway.
577 if (strlen(x) > 3)
578 (void)*(int*)0; // no-warning
579}
580
Jordy Rose6e4244e2012-05-14 17:58:35 +0000581void strncpy_zero(char *src) {
582 char dst[] = "123";
583 strncpy(dst, src, 0); // no-warning
584}
585
586void strncpy_empty() {
587 char dst[] = "123";
588 char src[] = "";
589 strncpy(dst, src, 4); // no-warning
590}
591
Jordy Rose5e5f1502011-06-20 03:49:16 +0000592//===----------------------------------------------------------------------===
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000593// strncat()
594//===----------------------------------------------------------------------===
595
596#ifdef VARIANT
597
598#define __strncat_chk BUILTIN(__strncat_chk)
599char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
600
601#define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
602
603#else /* VARIANT */
604
605#define strncat BUILTIN(strncat)
606char *strncat(char *restrict s1, const char *restrict s2, size_t n);
607
608#endif /* VARIANT */
609
610
611void strncat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000612 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000613}
614
615void strncat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000616 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000617}
618
619void strncat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000620 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 +0000621}
622
623void strncat_effects(char *y) {
624 char x[8] = "123";
625 size_t orig_len = strlen(x);
626 char a = x[0];
627
628 if (strlen(y) != 4)
629 return;
630
631 if (strncat(x, y, strlen(y)) != x)
632 (void)*(char*)0; // no-warning
633
634 if (strlen(x) != orig_len + strlen(y))
635 (void)*(char*)0; // no-warning
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000636}
637
638void strncat_overflow_0(char *y) {
639 char x[4] = "12";
640 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000641 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 +0000642}
643
644void strncat_overflow_1(char *y) {
645 char x[4] = "12";
646 if (strlen(y) == 3)
Jordy Rose8912aae2011-06-20 21:55:40 +0000647 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 +0000648}
649
650void strncat_overflow_2(char *y) {
651 char x[4] = "12";
652 if (strlen(y) == 2)
Jordy Rose8912aae2011-06-20 21:55:40 +0000653 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 +0000654}
655
656void strncat_overflow_3(char *y) {
657 char x[4] = "12";
658 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000659 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 +0000660}
661void strncat_no_overflow_1(char *y) {
662 char x[5] = "12";
663 if (strlen(y) == 2)
664 strncat(x, y, strlen(y)); // no-warning
665}
666
667void strncat_no_overflow_2(char *y) {
668 char x[4] = "12";
669 if (strlen(y) == 4)
670 strncat(x, y, 1); // no-warning
671}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000672
Jordy Rose8912aae2011-06-20 21:55:40 +0000673void strncat_symbolic_dst_length(char *dst) {
674 strncat(dst, "1234", 5);
675 if (strlen(dst) < 4)
676 (void)*(char*)0; // no-warning
677}
678
679void strncat_symbolic_src_length(char *src) {
680 char dst[8] = "1234";
681 strncat(dst, src, 3);
682 if (strlen(dst) < 4)
683 (void)*(char*)0; // no-warning
684
685 char dst2[8] = "1234";
686 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
687}
688
689void strncat_unknown_src_length(char *src, int offset) {
690 char dst[8] = "1234";
691 strncat(dst, &src[offset], 3);
692 if (strlen(dst) < 4)
693 (void)*(char*)0; // no-warning
694
695 char dst2[8] = "1234";
696 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
697}
698
699// There is no strncat_unknown_dst_length because if we can't get a symbolic
700// length for the "before" strlen, we won't be able to set one for "after".
701
702void strncat_symbolic_limit(unsigned limit) {
703 char dst[6] = "1234";
704 char src[] = "567";
705 strncat(dst, src, limit); // no-warning
706 if (strlen(dst) < 4)
707 (void)*(char*)0; // no-warning
708 if (strlen(dst) == 4)
709 (void)*(char*)0; // expected-warning{{null}}
710}
711
712void strncat_unknown_limit(float limit) {
713 char dst[6] = "1234";
714 char src[] = "567";
715 strncat(dst, src, (size_t)limit); // no-warning
716 if (strlen(dst) < 4)
717 (void)*(char*)0; // no-warning
718 if (strlen(dst) == 4)
719 (void)*(char*)0; // expected-warning{{null}}
720}
721
722void strncat_too_big(char *dst, char *src) {
723 if (strlen(dst) != (((size_t)0) - 2))
724 return;
725 if (strlen(src) != 2)
726 return;
727 strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
728}
729
Jordy Rose6e4244e2012-05-14 17:58:35 +0000730void strncat_zero(char *src) {
731 char dst[] = "123";
732 strncat(dst, src, 0); // no-warning
733}
734
735void strncat_empty() {
736 char dst[8] = "123";
737 char src[] = "";
738 strncat(dst, src, 4); // no-warning
739}
740
Lenny Maiorani318dd922011-04-12 17:08:43 +0000741//===----------------------------------------------------------------------===
742// strcmp()
743//===----------------------------------------------------------------------===
744
745#define strcmp BUILTIN(strcmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000746int strcmp(const char * s1, const char * s2);
Lenny Maiorani318dd922011-04-12 17:08:43 +0000747
748void strcmp_constant0() {
749 if (strcmp("123", "123") != 0)
750 (void)*(char*)0; // no-warning
751}
752
753void strcmp_constant_and_var_0() {
754 char *x = "123";
755 if (strcmp(x, "123") != 0)
756 (void)*(char*)0; // no-warning
757}
758
759void strcmp_constant_and_var_1() {
760 char *x = "123";
761 if (strcmp("123", x) != 0)
762 (void)*(char*)0; // no-warning
763}
764
765void strcmp_0() {
766 char *x = "123";
767 char *y = "123";
768 if (strcmp(x, y) != 0)
769 (void)*(char*)0; // no-warning
770}
771
772void strcmp_1() {
773 char *x = "234";
774 char *y = "123";
775 if (strcmp(x, y) != 1)
776 (void)*(char*)0; // no-warning
777}
778
779void strcmp_2() {
780 char *x = "123";
781 char *y = "234";
782 if (strcmp(x, y) != -1)
783 (void)*(char*)0; // no-warning
784}
785
786void strcmp_null_0() {
787 char *x = NULL;
788 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000789 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000790}
791
792void strcmp_null_1() {
793 char *x = "123";
794 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000795 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000796}
797
798void strcmp_diff_length_0() {
799 char *x = "12345";
800 char *y = "234";
801 if (strcmp(x, y) != -1)
802 (void)*(char*)0; // no-warning
803}
804
805void strcmp_diff_length_1() {
806 char *x = "123";
807 char *y = "23456";
808 if (strcmp(x, y) != -1)
809 (void)*(char*)0; // no-warning
810}
811
812void strcmp_diff_length_2() {
813 char *x = "12345";
814 char *y = "123";
815 if (strcmp(x, y) != 1)
816 (void)*(char*)0; // no-warning
817}
818
819void strcmp_diff_length_3() {
820 char *x = "123";
821 char *y = "12345";
822 if (strcmp(x, y) != -1)
823 (void)*(char*)0; // no-warning
824}
825
Jordy Roseadc42d42011-06-16 07:13:34 +0000826void strcmp_embedded_null () {
827 if (strcmp("\0z", "\0y") != 0)
828 (void)*(char*)0; // no-warning
829}
830
831void strcmp_unknown_arg (char *unknown) {
832 if (strcmp(unknown, unknown) != 0)
833 (void)*(char*)0; // no-warning
834}
835
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000836//===----------------------------------------------------------------------===
837// strncmp()
838//===----------------------------------------------------------------------===
839
840#define strncmp BUILTIN(strncmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000841int strncmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000842
843void strncmp_constant0() {
844 if (strncmp("123", "123", 3) != 0)
845 (void)*(char*)0; // no-warning
846}
847
848void strncmp_constant_and_var_0() {
849 char *x = "123";
850 if (strncmp(x, "123", 3) != 0)
851 (void)*(char*)0; // no-warning
852}
853
854void strncmp_constant_and_var_1() {
855 char *x = "123";
856 if (strncmp("123", x, 3) != 0)
857 (void)*(char*)0; // no-warning
858}
859
860void strncmp_0() {
861 char *x = "123";
862 char *y = "123";
863 if (strncmp(x, y, 3) != 0)
864 (void)*(char*)0; // no-warning
865}
866
867void strncmp_1() {
868 char *x = "234";
869 char *y = "123";
870 if (strncmp(x, y, 3) != 1)
871 (void)*(char*)0; // no-warning
872}
873
874void strncmp_2() {
875 char *x = "123";
876 char *y = "234";
877 if (strncmp(x, y, 3) != -1)
878 (void)*(char*)0; // no-warning
879}
880
881void strncmp_null_0() {
882 char *x = NULL;
883 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000884 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000885}
886
887void strncmp_null_1() {
888 char *x = "123";
889 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000890 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000891}
892
893void strncmp_diff_length_0() {
894 char *x = "12345";
895 char *y = "234";
896 if (strncmp(x, y, 5) != -1)
897 (void)*(char*)0; // no-warning
898}
899
900void strncmp_diff_length_1() {
901 char *x = "123";
902 char *y = "23456";
903 if (strncmp(x, y, 5) != -1)
904 (void)*(char*)0; // no-warning
905}
906
907void strncmp_diff_length_2() {
908 char *x = "12345";
909 char *y = "123";
910 if (strncmp(x, y, 5) != 1)
911 (void)*(char*)0; // no-warning
912}
913
914void strncmp_diff_length_3() {
915 char *x = "123";
916 char *y = "12345";
917 if (strncmp(x, y, 5) != -1)
918 (void)*(char*)0; // no-warning
919}
920
921void strncmp_diff_length_4() {
922 char *x = "123";
923 char *y = "12345";
924 if (strncmp(x, y, 3) != 0)
925 (void)*(char*)0; // no-warning
926}
927
928void strncmp_diff_length_5() {
929 char *x = "012";
930 char *y = "12345";
931 if (strncmp(x, y, 3) != -1)
932 (void)*(char*)0; // no-warning
933}
934
935void strncmp_diff_length_6() {
936 char *x = "234";
937 char *y = "12345";
938 if (strncmp(x, y, 3) != 1)
939 (void)*(char*)0; // no-warning
940}
941
Jordy Roseadc42d42011-06-16 07:13:34 +0000942void strncmp_embedded_null () {
943 if (strncmp("ab\0zz", "ab\0yy", 4) != 0)
944 (void)*(char*)0; // no-warning
945}
946
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000947//===----------------------------------------------------------------------===
948// strcasecmp()
949//===----------------------------------------------------------------------===
950
951#define strcasecmp BUILTIN(strcasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000952int strcasecmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000953
954void strcasecmp_constant0() {
955 if (strcasecmp("abc", "Abc") != 0)
956 (void)*(char*)0; // no-warning
957}
958
959void strcasecmp_constant_and_var_0() {
960 char *x = "abc";
961 if (strcasecmp(x, "Abc") != 0)
962 (void)*(char*)0; // no-warning
963}
964
965void strcasecmp_constant_and_var_1() {
966 char *x = "abc";
967 if (strcasecmp("Abc", x) != 0)
968 (void)*(char*)0; // no-warning
969}
970
971void strcasecmp_0() {
972 char *x = "abc";
973 char *y = "Abc";
974 if (strcasecmp(x, y) != 0)
975 (void)*(char*)0; // no-warning
976}
977
978void strcasecmp_1() {
979 char *x = "Bcd";
980 char *y = "abc";
981 if (strcasecmp(x, y) != 1)
982 (void)*(char*)0; // no-warning
983}
984
985void strcasecmp_2() {
986 char *x = "abc";
987 char *y = "Bcd";
988 if (strcasecmp(x, y) != -1)
989 (void)*(char*)0; // no-warning
990}
991
992void strcasecmp_null_0() {
993 char *x = NULL;
994 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000995 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000996}
997
998void strcasecmp_null_1() {
999 char *x = "123";
1000 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001001 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +00001002}
1003
1004void strcasecmp_diff_length_0() {
1005 char *x = "abcde";
1006 char *y = "aBd";
1007 if (strcasecmp(x, y) != -1)
1008 (void)*(char*)0; // no-warning
1009}
1010
1011void strcasecmp_diff_length_1() {
1012 char *x = "abc";
1013 char *y = "aBdef";
1014 if (strcasecmp(x, y) != -1)
1015 (void)*(char*)0; // no-warning
1016}
1017
1018void strcasecmp_diff_length_2() {
1019 char *x = "aBcDe";
1020 char *y = "abc";
1021 if (strcasecmp(x, y) != 1)
1022 (void)*(char*)0; // no-warning
1023}
1024
1025void strcasecmp_diff_length_3() {
1026 char *x = "aBc";
1027 char *y = "abcde";
1028 if (strcasecmp(x, y) != -1)
1029 (void)*(char*)0; // no-warning
1030}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001031
Jordy Roseadc42d42011-06-16 07:13:34 +00001032void strcasecmp_embedded_null () {
1033 if (strcasecmp("ab\0zz", "ab\0yy") != 0)
1034 (void)*(char*)0; // no-warning
1035}
1036
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001037//===----------------------------------------------------------------------===
1038// strncasecmp()
1039//===----------------------------------------------------------------------===
1040
1041#define strncasecmp BUILTIN(strncasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +00001042int strncasecmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001043
1044void strncasecmp_constant0() {
1045 if (strncasecmp("abc", "Abc", 3) != 0)
1046 (void)*(char*)0; // no-warning
1047}
1048
1049void strncasecmp_constant_and_var_0() {
1050 char *x = "abc";
1051 if (strncasecmp(x, "Abc", 3) != 0)
1052 (void)*(char*)0; // no-warning
1053}
1054
1055void strncasecmp_constant_and_var_1() {
1056 char *x = "abc";
1057 if (strncasecmp("Abc", x, 3) != 0)
1058 (void)*(char*)0; // no-warning
1059}
1060
1061void strncasecmp_0() {
1062 char *x = "abc";
1063 char *y = "Abc";
1064 if (strncasecmp(x, y, 3) != 0)
1065 (void)*(char*)0; // no-warning
1066}
1067
1068void strncasecmp_1() {
1069 char *x = "Bcd";
1070 char *y = "abc";
1071 if (strncasecmp(x, y, 3) != 1)
1072 (void)*(char*)0; // no-warning
1073}
1074
1075void strncasecmp_2() {
1076 char *x = "abc";
1077 char *y = "Bcd";
1078 if (strncasecmp(x, y, 3) != -1)
1079 (void)*(char*)0; // no-warning
1080}
1081
1082void strncasecmp_null_0() {
1083 char *x = NULL;
1084 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001085 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001086}
1087
1088void strncasecmp_null_1() {
1089 char *x = "123";
1090 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001091 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001092}
1093
1094void strncasecmp_diff_length_0() {
1095 char *x = "abcde";
1096 char *y = "aBd";
1097 if (strncasecmp(x, y, 5) != -1)
1098 (void)*(char*)0; // no-warning
1099}
1100
1101void strncasecmp_diff_length_1() {
1102 char *x = "abc";
1103 char *y = "aBdef";
1104 if (strncasecmp(x, y, 5) != -1)
1105 (void)*(char*)0; // no-warning
1106}
1107
1108void strncasecmp_diff_length_2() {
1109 char *x = "aBcDe";
1110 char *y = "abc";
1111 if (strncasecmp(x, y, 5) != 1)
1112 (void)*(char*)0; // no-warning
1113}
1114
1115void strncasecmp_diff_length_3() {
1116 char *x = "aBc";
1117 char *y = "abcde";
1118 if (strncasecmp(x, y, 5) != -1)
1119 (void)*(char*)0; // no-warning
1120}
1121
1122void strncasecmp_diff_length_4() {
1123 char *x = "abcde";
1124 char *y = "aBc";
1125 if (strncasecmp(x, y, 3) != 0)
1126 (void)*(char*)0; // no-warning
1127}
1128
1129void strncasecmp_diff_length_5() {
1130 char *x = "abcde";
1131 char *y = "aBd";
1132 if (strncasecmp(x, y, 3) != -1)
1133 (void)*(char*)0; // no-warning
1134}
1135
1136void strncasecmp_diff_length_6() {
1137 char *x = "aBDe";
1138 char *y = "abc";
1139 if (strncasecmp(x, y, 3) != 1)
1140 (void)*(char*)0; // no-warning
1141}
Jordy Roseadc42d42011-06-16 07:13:34 +00001142
1143void strncasecmp_embedded_null () {
1144 if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0)
1145 (void)*(char*)0; // no-warning
1146}
Jordy Rose14d20b12012-05-03 07:34:01 +00001147
1148//===----------------------------------------------------------------------===
1149// Miscellaneous extras.
1150//===----------------------------------------------------------------------===
1151
1152// See additive-folding.cpp for a description of this bug.
1153// This test is insurance in case we significantly change how SymExprs are
1154// evaluated. It isn't as good as additive-folding.cpp's version
1155// because it will only actually be a test on systems where
1156// sizeof(1 == 1) < sizeof(size_t).
1157// We could add a triple if it becomes necessary.
1158void PR12206(const char *x) {
1159 // This test is only useful under these conditions.
1160 size_t comparisonSize = sizeof(1 == 1);
1161 if (sizeof(size_t) <= comparisonSize) return;
1162
1163 // Create a value that requires more bits to store than a comparison result.
1164 size_t value = 1UL;
1165 value <<= 8 * comparisonSize;
1166 value += 1;
1167
1168 // Constrain the length of x.
1169 if (strlen(x) != value) return;
1170
1171 // Test relational operators.
1172 if (strlen(x) < 2) { (void)*(char*)0; } // no-warning
1173 if (2 > strlen(x)) { (void)*(char*)0; } // no-warning
1174
1175 // Test equality operators.
1176 if (strlen(x) == 1) { (void)*(char*)0; } // no-warning
1177 if (1 == strlen(x)) { (void)*(char*)0; } // no-warning
1178}