blob: 24e29ebb02b39806919777e2eeccd72dcc7e0790 [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
581//===----------------------------------------------------------------------===
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000582// strncat()
583//===----------------------------------------------------------------------===
584
585#ifdef VARIANT
586
587#define __strncat_chk BUILTIN(__strncat_chk)
588char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
589
590#define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
591
592#else /* VARIANT */
593
594#define strncat BUILTIN(strncat)
595char *strncat(char *restrict s1, const char *restrict s2, size_t n);
596
597#endif /* VARIANT */
598
599
600void strncat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000601 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000602}
603
604void strncat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000605 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000606}
607
608void strncat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000609 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 +0000610}
611
612void strncat_effects(char *y) {
613 char x[8] = "123";
614 size_t orig_len = strlen(x);
615 char a = x[0];
616
617 if (strlen(y) != 4)
618 return;
619
620 if (strncat(x, y, strlen(y)) != x)
621 (void)*(char*)0; // no-warning
622
623 if (strlen(x) != orig_len + strlen(y))
624 (void)*(char*)0; // no-warning
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000625}
626
627void strncat_overflow_0(char *y) {
628 char x[4] = "12";
629 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000630 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 +0000631}
632
633void strncat_overflow_1(char *y) {
634 char x[4] = "12";
635 if (strlen(y) == 3)
Jordy Rose8912aae2011-06-20 21:55:40 +0000636 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 +0000637}
638
639void strncat_overflow_2(char *y) {
640 char x[4] = "12";
641 if (strlen(y) == 2)
Jordy Rose8912aae2011-06-20 21:55:40 +0000642 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 +0000643}
644
645void strncat_overflow_3(char *y) {
646 char x[4] = "12";
647 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000648 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 +0000649}
650void strncat_no_overflow_1(char *y) {
651 char x[5] = "12";
652 if (strlen(y) == 2)
653 strncat(x, y, strlen(y)); // no-warning
654}
655
656void strncat_no_overflow_2(char *y) {
657 char x[4] = "12";
658 if (strlen(y) == 4)
659 strncat(x, y, 1); // no-warning
660}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000661
Jordy Rose8912aae2011-06-20 21:55:40 +0000662void strncat_symbolic_dst_length(char *dst) {
663 strncat(dst, "1234", 5);
664 if (strlen(dst) < 4)
665 (void)*(char*)0; // no-warning
666}
667
668void strncat_symbolic_src_length(char *src) {
669 char dst[8] = "1234";
670 strncat(dst, src, 3);
671 if (strlen(dst) < 4)
672 (void)*(char*)0; // no-warning
673
674 char dst2[8] = "1234";
675 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
676}
677
678void strncat_unknown_src_length(char *src, int offset) {
679 char dst[8] = "1234";
680 strncat(dst, &src[offset], 3);
681 if (strlen(dst) < 4)
682 (void)*(char*)0; // no-warning
683
684 char dst2[8] = "1234";
685 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
686}
687
688// There is no strncat_unknown_dst_length because if we can't get a symbolic
689// length for the "before" strlen, we won't be able to set one for "after".
690
691void strncat_symbolic_limit(unsigned limit) {
692 char dst[6] = "1234";
693 char src[] = "567";
694 strncat(dst, src, limit); // no-warning
695 if (strlen(dst) < 4)
696 (void)*(char*)0; // no-warning
697 if (strlen(dst) == 4)
698 (void)*(char*)0; // expected-warning{{null}}
699}
700
701void strncat_unknown_limit(float limit) {
702 char dst[6] = "1234";
703 char src[] = "567";
704 strncat(dst, src, (size_t)limit); // no-warning
705 if (strlen(dst) < 4)
706 (void)*(char*)0; // no-warning
707 if (strlen(dst) == 4)
708 (void)*(char*)0; // expected-warning{{null}}
709}
710
711void strncat_too_big(char *dst, char *src) {
712 if (strlen(dst) != (((size_t)0) - 2))
713 return;
714 if (strlen(src) != 2)
715 return;
716 strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
717}
718
Lenny Maiorani318dd922011-04-12 17:08:43 +0000719//===----------------------------------------------------------------------===
720// strcmp()
721//===----------------------------------------------------------------------===
722
723#define strcmp BUILTIN(strcmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000724int strcmp(const char * s1, const char * s2);
Lenny Maiorani318dd922011-04-12 17:08:43 +0000725
726void strcmp_constant0() {
727 if (strcmp("123", "123") != 0)
728 (void)*(char*)0; // no-warning
729}
730
731void strcmp_constant_and_var_0() {
732 char *x = "123";
733 if (strcmp(x, "123") != 0)
734 (void)*(char*)0; // no-warning
735}
736
737void strcmp_constant_and_var_1() {
738 char *x = "123";
739 if (strcmp("123", x) != 0)
740 (void)*(char*)0; // no-warning
741}
742
743void strcmp_0() {
744 char *x = "123";
745 char *y = "123";
746 if (strcmp(x, y) != 0)
747 (void)*(char*)0; // no-warning
748}
749
750void strcmp_1() {
751 char *x = "234";
752 char *y = "123";
753 if (strcmp(x, y) != 1)
754 (void)*(char*)0; // no-warning
755}
756
757void strcmp_2() {
758 char *x = "123";
759 char *y = "234";
760 if (strcmp(x, y) != -1)
761 (void)*(char*)0; // no-warning
762}
763
764void strcmp_null_0() {
765 char *x = NULL;
766 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000767 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000768}
769
770void strcmp_null_1() {
771 char *x = "123";
772 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000773 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000774}
775
776void strcmp_diff_length_0() {
777 char *x = "12345";
778 char *y = "234";
779 if (strcmp(x, y) != -1)
780 (void)*(char*)0; // no-warning
781}
782
783void strcmp_diff_length_1() {
784 char *x = "123";
785 char *y = "23456";
786 if (strcmp(x, y) != -1)
787 (void)*(char*)0; // no-warning
788}
789
790void strcmp_diff_length_2() {
791 char *x = "12345";
792 char *y = "123";
793 if (strcmp(x, y) != 1)
794 (void)*(char*)0; // no-warning
795}
796
797void strcmp_diff_length_3() {
798 char *x = "123";
799 char *y = "12345";
800 if (strcmp(x, y) != -1)
801 (void)*(char*)0; // no-warning
802}
803
Jordy Roseadc42d42011-06-16 07:13:34 +0000804void strcmp_embedded_null () {
805 if (strcmp("\0z", "\0y") != 0)
806 (void)*(char*)0; // no-warning
807}
808
809void strcmp_unknown_arg (char *unknown) {
810 if (strcmp(unknown, unknown) != 0)
811 (void)*(char*)0; // no-warning
812}
813
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000814//===----------------------------------------------------------------------===
815// strncmp()
816//===----------------------------------------------------------------------===
817
818#define strncmp BUILTIN(strncmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000819int strncmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000820
821void strncmp_constant0() {
822 if (strncmp("123", "123", 3) != 0)
823 (void)*(char*)0; // no-warning
824}
825
826void strncmp_constant_and_var_0() {
827 char *x = "123";
828 if (strncmp(x, "123", 3) != 0)
829 (void)*(char*)0; // no-warning
830}
831
832void strncmp_constant_and_var_1() {
833 char *x = "123";
834 if (strncmp("123", x, 3) != 0)
835 (void)*(char*)0; // no-warning
836}
837
838void strncmp_0() {
839 char *x = "123";
840 char *y = "123";
841 if (strncmp(x, y, 3) != 0)
842 (void)*(char*)0; // no-warning
843}
844
845void strncmp_1() {
846 char *x = "234";
847 char *y = "123";
848 if (strncmp(x, y, 3) != 1)
849 (void)*(char*)0; // no-warning
850}
851
852void strncmp_2() {
853 char *x = "123";
854 char *y = "234";
855 if (strncmp(x, y, 3) != -1)
856 (void)*(char*)0; // no-warning
857}
858
859void strncmp_null_0() {
860 char *x = NULL;
861 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000862 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000863}
864
865void strncmp_null_1() {
866 char *x = "123";
867 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000868 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000869}
870
871void strncmp_diff_length_0() {
872 char *x = "12345";
873 char *y = "234";
874 if (strncmp(x, y, 5) != -1)
875 (void)*(char*)0; // no-warning
876}
877
878void strncmp_diff_length_1() {
879 char *x = "123";
880 char *y = "23456";
881 if (strncmp(x, y, 5) != -1)
882 (void)*(char*)0; // no-warning
883}
884
885void strncmp_diff_length_2() {
886 char *x = "12345";
887 char *y = "123";
888 if (strncmp(x, y, 5) != 1)
889 (void)*(char*)0; // no-warning
890}
891
892void strncmp_diff_length_3() {
893 char *x = "123";
894 char *y = "12345";
895 if (strncmp(x, y, 5) != -1)
896 (void)*(char*)0; // no-warning
897}
898
899void strncmp_diff_length_4() {
900 char *x = "123";
901 char *y = "12345";
902 if (strncmp(x, y, 3) != 0)
903 (void)*(char*)0; // no-warning
904}
905
906void strncmp_diff_length_5() {
907 char *x = "012";
908 char *y = "12345";
909 if (strncmp(x, y, 3) != -1)
910 (void)*(char*)0; // no-warning
911}
912
913void strncmp_diff_length_6() {
914 char *x = "234";
915 char *y = "12345";
916 if (strncmp(x, y, 3) != 1)
917 (void)*(char*)0; // no-warning
918}
919
Jordy Roseadc42d42011-06-16 07:13:34 +0000920void strncmp_embedded_null () {
921 if (strncmp("ab\0zz", "ab\0yy", 4) != 0)
922 (void)*(char*)0; // no-warning
923}
924
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000925//===----------------------------------------------------------------------===
926// strcasecmp()
927//===----------------------------------------------------------------------===
928
929#define strcasecmp BUILTIN(strcasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000930int strcasecmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000931
932void strcasecmp_constant0() {
933 if (strcasecmp("abc", "Abc") != 0)
934 (void)*(char*)0; // no-warning
935}
936
937void strcasecmp_constant_and_var_0() {
938 char *x = "abc";
939 if (strcasecmp(x, "Abc") != 0)
940 (void)*(char*)0; // no-warning
941}
942
943void strcasecmp_constant_and_var_1() {
944 char *x = "abc";
945 if (strcasecmp("Abc", x) != 0)
946 (void)*(char*)0; // no-warning
947}
948
949void strcasecmp_0() {
950 char *x = "abc";
951 char *y = "Abc";
952 if (strcasecmp(x, y) != 0)
953 (void)*(char*)0; // no-warning
954}
955
956void strcasecmp_1() {
957 char *x = "Bcd";
958 char *y = "abc";
959 if (strcasecmp(x, y) != 1)
960 (void)*(char*)0; // no-warning
961}
962
963void strcasecmp_2() {
964 char *x = "abc";
965 char *y = "Bcd";
966 if (strcasecmp(x, y) != -1)
967 (void)*(char*)0; // no-warning
968}
969
970void strcasecmp_null_0() {
971 char *x = NULL;
972 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000973 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000974}
975
976void strcasecmp_null_1() {
977 char *x = "123";
978 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000979 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000980}
981
982void strcasecmp_diff_length_0() {
983 char *x = "abcde";
984 char *y = "aBd";
985 if (strcasecmp(x, y) != -1)
986 (void)*(char*)0; // no-warning
987}
988
989void strcasecmp_diff_length_1() {
990 char *x = "abc";
991 char *y = "aBdef";
992 if (strcasecmp(x, y) != -1)
993 (void)*(char*)0; // no-warning
994}
995
996void strcasecmp_diff_length_2() {
997 char *x = "aBcDe";
998 char *y = "abc";
999 if (strcasecmp(x, y) != 1)
1000 (void)*(char*)0; // no-warning
1001}
1002
1003void strcasecmp_diff_length_3() {
1004 char *x = "aBc";
1005 char *y = "abcde";
1006 if (strcasecmp(x, y) != -1)
1007 (void)*(char*)0; // no-warning
1008}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001009
Jordy Roseadc42d42011-06-16 07:13:34 +00001010void strcasecmp_embedded_null () {
1011 if (strcasecmp("ab\0zz", "ab\0yy") != 0)
1012 (void)*(char*)0; // no-warning
1013}
1014
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001015//===----------------------------------------------------------------------===
1016// strncasecmp()
1017//===----------------------------------------------------------------------===
1018
1019#define strncasecmp BUILTIN(strncasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +00001020int strncasecmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001021
1022void strncasecmp_constant0() {
1023 if (strncasecmp("abc", "Abc", 3) != 0)
1024 (void)*(char*)0; // no-warning
1025}
1026
1027void strncasecmp_constant_and_var_0() {
1028 char *x = "abc";
1029 if (strncasecmp(x, "Abc", 3) != 0)
1030 (void)*(char*)0; // no-warning
1031}
1032
1033void strncasecmp_constant_and_var_1() {
1034 char *x = "abc";
1035 if (strncasecmp("Abc", x, 3) != 0)
1036 (void)*(char*)0; // no-warning
1037}
1038
1039void strncasecmp_0() {
1040 char *x = "abc";
1041 char *y = "Abc";
1042 if (strncasecmp(x, y, 3) != 0)
1043 (void)*(char*)0; // no-warning
1044}
1045
1046void strncasecmp_1() {
1047 char *x = "Bcd";
1048 char *y = "abc";
1049 if (strncasecmp(x, y, 3) != 1)
1050 (void)*(char*)0; // no-warning
1051}
1052
1053void strncasecmp_2() {
1054 char *x = "abc";
1055 char *y = "Bcd";
1056 if (strncasecmp(x, y, 3) != -1)
1057 (void)*(char*)0; // no-warning
1058}
1059
1060void strncasecmp_null_0() {
1061 char *x = NULL;
1062 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001063 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001064}
1065
1066void strncasecmp_null_1() {
1067 char *x = "123";
1068 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +00001069 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001070}
1071
1072void strncasecmp_diff_length_0() {
1073 char *x = "abcde";
1074 char *y = "aBd";
1075 if (strncasecmp(x, y, 5) != -1)
1076 (void)*(char*)0; // no-warning
1077}
1078
1079void strncasecmp_diff_length_1() {
1080 char *x = "abc";
1081 char *y = "aBdef";
1082 if (strncasecmp(x, y, 5) != -1)
1083 (void)*(char*)0; // no-warning
1084}
1085
1086void strncasecmp_diff_length_2() {
1087 char *x = "aBcDe";
1088 char *y = "abc";
1089 if (strncasecmp(x, y, 5) != 1)
1090 (void)*(char*)0; // no-warning
1091}
1092
1093void strncasecmp_diff_length_3() {
1094 char *x = "aBc";
1095 char *y = "abcde";
1096 if (strncasecmp(x, y, 5) != -1)
1097 (void)*(char*)0; // no-warning
1098}
1099
1100void strncasecmp_diff_length_4() {
1101 char *x = "abcde";
1102 char *y = "aBc";
1103 if (strncasecmp(x, y, 3) != 0)
1104 (void)*(char*)0; // no-warning
1105}
1106
1107void strncasecmp_diff_length_5() {
1108 char *x = "abcde";
1109 char *y = "aBd";
1110 if (strncasecmp(x, y, 3) != -1)
1111 (void)*(char*)0; // no-warning
1112}
1113
1114void strncasecmp_diff_length_6() {
1115 char *x = "aBDe";
1116 char *y = "abc";
1117 if (strncasecmp(x, y, 3) != 1)
1118 (void)*(char*)0; // no-warning
1119}
Jordy Roseadc42d42011-06-16 07:13:34 +00001120
1121void strncasecmp_embedded_null () {
1122 if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0)
1123 (void)*(char*)0; // no-warning
1124}
Jordy Rose14d20b12012-05-03 07:34:01 +00001125
1126//===----------------------------------------------------------------------===
1127// Miscellaneous extras.
1128//===----------------------------------------------------------------------===
1129
1130// See additive-folding.cpp for a description of this bug.
1131// This test is insurance in case we significantly change how SymExprs are
1132// evaluated. It isn't as good as additive-folding.cpp's version
1133// because it will only actually be a test on systems where
1134// sizeof(1 == 1) < sizeof(size_t).
1135// We could add a triple if it becomes necessary.
1136void PR12206(const char *x) {
1137 // This test is only useful under these conditions.
1138 size_t comparisonSize = sizeof(1 == 1);
1139 if (sizeof(size_t) <= comparisonSize) return;
1140
1141 // Create a value that requires more bits to store than a comparison result.
1142 size_t value = 1UL;
1143 value <<= 8 * comparisonSize;
1144 value += 1;
1145
1146 // Constrain the length of x.
1147 if (strlen(x) != value) return;
1148
1149 // Test relational operators.
1150 if (strlen(x) < 2) { (void)*(char*)0; } // no-warning
1151 if (2 > strlen(x)) { (void)*(char*)0; } // no-warning
1152
1153 // Test equality operators.
1154 if (strlen(x) == 1) { (void)*(char*)0; } // no-warning
1155 if (1 == strlen(x)) { (void)*(char*)0; } // no-warning
1156}