blob: 74cf33c4bc224fb7e4e8b8fbf80c2bb8921fff4c [file] [log] [blame]
Ted Kremenekcdc3a892012-08-24 20:39:55 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -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;
Jordy Rose43d9f0d2012-05-16 16:01:10 +000029
30void clang_analyzer_eval(int);
31
Anna Zakse3d250e2011-12-11 18:43:40 +000032int scanf(const char *restrict format, ...);
Jordy Rose19c5dd12010-07-27 01:37:31 +000033
34//===----------------------------------------------------------------------===
35// strlen()
36//===----------------------------------------------------------------------===
37
38#define strlen BUILTIN(strlen)
39size_t strlen(const char *s);
40
41void strlen_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +000042 clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}}
Jordy Rose19c5dd12010-07-27 01:37:31 +000043}
44
45void strlen_constant1() {
46 const char *a = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +000047 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
Jordy Rose19c5dd12010-07-27 01:37:31 +000048}
49
50void strlen_constant2(char x) {
51 char a[] = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +000052 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
53
Jordy Rose19c5dd12010-07-27 01:37:31 +000054 a[0] = x;
Jordy Rose43d9f0d2012-05-16 16:01:10 +000055 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
Jordy Rose19c5dd12010-07-27 01:37:31 +000056}
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);
Jordy Rose43d9f0d2012-05-16 16:01:10 +000081 if (a == 0)
82 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
Jordy Rosea5261542010-08-14 21:02:52 +000083
84 use_two_strings(&z);
85
86 size_t c = strlen(z.a);
Jordy Rose43d9f0d2012-05-16 16:01:10 +000087 if (a == 0)
88 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
Jordy Rosea5261542010-08-14 21:02:52 +000089}
90
91extern void use_string(char *);
92void strlen_argument(char *x) {
93 size_t a = strlen(x);
94 size_t b = strlen(x);
Jordy Rose43d9f0d2012-05-16 16:01:10 +000095 if (a == 0)
96 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
Jordy Rosea5261542010-08-14 21:02:52 +000097
98 use_string(x);
99
100 size_t c = strlen(x);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000101 if (a == 0)
102 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
Jordy Rosea5261542010-08-14 21:02:52 +0000103}
104
105extern char global_str[];
106void strlen_global() {
107 size_t a = strlen(global_str);
108 size_t b = strlen(global_str);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000109 if (a == 0) {
110 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
111 // Make sure clang_analyzer_eval does not invalidate globals.
112 clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}}
113 }
Jordy Rosea5261542010-08-14 21:02:52 +0000114
115 // Call a function with unknown effects, which should invalidate globals.
116 use_string(0);
117
118 size_t c = strlen(global_str);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000119 if (a == 0)
120 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
Jordy Rosea5261542010-08-14 21:02:52 +0000121}
122
123void strlen_indirect(char *x) {
124 size_t a = strlen(x);
125 char *p = x;
126 char **p2 = &p;
127 size_t b = strlen(x);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000128 if (a == 0)
129 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
Jordy Rosea5261542010-08-14 21:02:52 +0000130
131 extern void use_string_ptr(char*const*);
132 use_string_ptr(p2);
133
134 size_t c = strlen(x);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000135 if (a == 0)
136 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
Jordy Rosea5261542010-08-14 21:02:52 +0000137}
138
Anna Zaks2cbe7912011-12-20 22:35:30 +0000139void strlen_indirect2(char *x) {
140 size_t a = strlen(x);
141 char *p = x;
142 char **p2 = &p;
143 extern void use_string_ptr2(char**);
144 use_string_ptr2(p2);
145
146 size_t c = strlen(x);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000147 if (a == 0)
148 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
Anna Zaks2cbe7912011-12-20 22:35:30 +0000149}
150
Jordy Rosea5261542010-08-14 21:02:52 +0000151void strlen_liveness(const char *x) {
152 if (strlen(x) < 5)
153 return;
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000154 clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
Jordy Rosea5261542010-08-14 21:02:52 +0000155}
Jordy Rosee64f3112010-08-16 07:51:42 +0000156
157//===----------------------------------------------------------------------===
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000158// strnlen()
159//===----------------------------------------------------------------------===
160
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000161size_t strnlen(const char *s, size_t maxlen);
162
163void strnlen_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000164 clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000165}
166
167void strnlen_constant1() {
168 const char *a = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000169 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000170}
171
172void strnlen_constant2(char x) {
173 char a[] = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000174 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000175 a[0] = x;
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000176 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000177}
178
179void strnlen_constant4() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000180 clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000181}
182
183void strnlen_constant5() {
184 const char *a = "123456";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000185 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000186}
187
188void strnlen_constant6(char x) {
189 char a[] = "123456";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000190 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000191 a[0] = x;
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000192 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000193}
194
195size_t strnlen_null() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000196 return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}}
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000197}
198
199size_t strnlen_fn() {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000200 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 +0000201}
202
203size_t strnlen_nonloc() {
204label:
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000205 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 +0000206}
207
Jordy Rose793bff32011-06-14 01:15:31 +0000208void strnlen_zero() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000209 clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}}
210 clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}}
Jordy Rose793bff32011-06-14 01:15:31 +0000211}
212
213size_t strnlen_compound_literal() {
214 // This used to crash because we don't model the string lengths of
215 // compound literals.
216 return strnlen((char[]) { 'a', 'b', 0 }, 1);
217}
218
219size_t strnlen_unknown_limit(float f) {
220 // This used to crash because we don't model the integer values of floats.
221 return strnlen("abc", (int)f);
222}
223
224void strnlen_is_not_strlen(char *x) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000225 clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}}
Jordy Rose793bff32011-06-14 01:15:31 +0000226}
227
228void strnlen_at_limit(char *x) {
229 size_t len = strnlen(x, 10);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000230 clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}}
231 clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}}
232 clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}}
Jordy Rose793bff32011-06-14 01:15:31 +0000233}
234
235void strnlen_at_actual(size_t limit) {
236 size_t len = strnlen("abc", limit);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000237 clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}}
238 // This is due to eager assertion in strnlen.
239 if (limit == 0) {
240 clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
241 } else {
242 clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}}
243 clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}}
244 }
Ted Kremenekbe4242c2011-02-22 04:55:05 +0000245}
246
247//===----------------------------------------------------------------------===
Jordy Rosee64f3112010-08-16 07:51:42 +0000248// strcpy()
249//===----------------------------------------------------------------------===
250
251#ifdef VARIANT
252
253#define __strcpy_chk BUILTIN(__strcpy_chk)
254char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
255
256#define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
257
258#else /* VARIANT */
259
260#define strcpy BUILTIN(strcpy)
261char *strcpy(char *restrict s1, const char *restrict s2);
262
263#endif /* VARIANT */
264
265
266void strcpy_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000267 strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000268}
269
270void strcpy_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000271 strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000272}
273
274void strcpy_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000275 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 +0000276}
277
Anna Zaksce8ef162012-01-13 00:56:48 +0000278void strcpy_fn_const(char *x) {
279 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}}
280}
281
Jordan Rosef8e2c062013-03-20 20:36:01 +0000282extern int globalInt;
Jordy Rosee64f3112010-08-16 07:51:42 +0000283void strcpy_effects(char *x, char *y) {
284 char a = x[0];
Jordan Rosef8e2c062013-03-20 20:36:01 +0000285 if (globalInt != 42)
286 return;
Jordy Rosee64f3112010-08-16 07:51:42 +0000287
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000288 clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
289 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
290 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
Jordan Rosef8e2c062013-03-20 20:36:01 +0000291 clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000292}
293
294void strcpy_overflow(char *y) {
295 char x[4];
296 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000297 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000298}
299
300void strcpy_no_overflow(char *y) {
301 char x[4];
302 if (strlen(y) == 3)
303 strcpy(x, y); // no-warning
304}
305
306//===----------------------------------------------------------------------===
307// stpcpy()
308//===----------------------------------------------------------------------===
309
310#ifdef VARIANT
311
312#define __stpcpy_chk BUILTIN(__stpcpy_chk)
313char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
314
315#define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
316
317#else /* VARIANT */
318
319#define stpcpy BUILTIN(stpcpy)
320char *stpcpy(char *restrict s1, const char *restrict s2);
321
322#endif /* VARIANT */
323
324
325void stpcpy_effect(char *x, char *y) {
326 char a = x[0];
327
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000328 clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}}
329 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
330 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000331}
332
333void stpcpy_overflow(char *y) {
334 char x[4];
335 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000336 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000337}
338
339void stpcpy_no_overflow(char *y) {
340 char x[4];
341 if (strlen(y) == 3)
342 stpcpy(x, y); // no-warning
343}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000344
345//===----------------------------------------------------------------------===
346// strcat()
347//===----------------------------------------------------------------------===
348
349#ifdef VARIANT
350
351#define __strcat_chk BUILTIN(__strcat_chk)
352char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
353
354#define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
355
356#else /* VARIANT */
357
358#define strcat BUILTIN(strcat)
359char *strcat(char *restrict s1, const char *restrict s2);
360
361#endif /* VARIANT */
362
363
364void strcat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000365 strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000366}
367
368void strcat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000369 strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000370}
371
372void strcat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000373 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 +0000374}
375
376void strcat_effects(char *y) {
377 char x[8] = "123";
378 size_t orig_len = strlen(x);
379 char a = x[0];
380
381 if (strlen(y) != 4)
382 return;
383
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000384 clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
385 clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000386}
387
388void strcat_overflow_0(char *y) {
389 char x[4] = "12";
390 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000391 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000392}
393
394void strcat_overflow_1(char *y) {
395 char x[4] = "12";
396 if (strlen(y) == 3)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000397 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000398}
399
400void strcat_overflow_2(char *y) {
401 char x[4] = "12";
402 if (strlen(y) == 2)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000403 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000404}
405
406void strcat_no_overflow(char *y) {
407 char x[5] = "12";
408 if (strlen(y) == 2)
409 strcat(x, y); // no-warning
410}
411
Jordy Rosed5af0e12011-06-15 05:52:56 +0000412void strcat_symbolic_dst_length(char *dst) {
413 strcat(dst, "1234");
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000414 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rosed5af0e12011-06-15 05:52:56 +0000415}
416
Anna Zakse3d250e2011-12-11 18:43:40 +0000417void strcat_symbolic_dst_length_taint(char *dst) {
418 scanf("%s", dst); // Taint data.
419 strcat(dst, "1234");
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000420 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Anna Zakse3d250e2011-12-11 18:43:40 +0000421}
422
Jordy Rosed5af0e12011-06-15 05:52:56 +0000423void strcat_unknown_src_length(char *src, int offset) {
424 char dst[8] = "1234";
425 strcat(dst, &src[offset]);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000426 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rosed5af0e12011-06-15 05:52:56 +0000427}
428
429// There is no strcat_unknown_dst_length because if we can't get a symbolic
430// length for the "before" strlen, we won't be able to set one for "after".
431
432void strcat_too_big(char *dst, char *src) {
433 if (strlen(dst) != (((size_t)0) - 2))
434 return;
435 if (strlen(src) != 2)
436 return;
437 strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
438}
439
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000440
441//===----------------------------------------------------------------------===
Jordy Rose5e5f1502011-06-20 03:49:16 +0000442// strncpy()
443//===----------------------------------------------------------------------===
444
445#ifdef VARIANT
446
447#define __strncpy_chk BUILTIN(__strncpy_chk)
448char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
449
450#define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
451
452#else /* VARIANT */
453
454#define strncpy BUILTIN(strncpy)
455char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
456
457#endif /* VARIANT */
458
459
460void strncpy_null_dst(char *x) {
461 strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
462}
463
464void strncpy_null_src(char *x) {
465 strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
466}
467
468void strncpy_fn(char *x) {
469 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}}
470}
471
472void strncpy_effects(char *x, char *y) {
473 char a = x[0];
474
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000475 clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
476 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
477 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
Jordy Rose5e5f1502011-06-20 03:49:16 +0000478}
479
480void strncpy_overflow(char *y) {
481 char x[4];
482 if (strlen(y) == 4)
483 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
484}
485
486void strncpy_no_overflow(char *y) {
487 char x[4];
488 if (strlen(y) == 3)
489 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
490}
491
492void strncpy_no_overflow2(char *y, int n) {
493 if (n <= 4)
494 return;
495
496 char x[4];
497 if (strlen(y) == 3)
498 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
499}
500
501void strncpy_truncate(char *y) {
502 char x[4];
503 if (strlen(y) == 4)
504 strncpy(x, y, 3); // no-warning
505}
506
507void strncpy_no_truncate(char *y) {
508 char x[4];
509 if (strlen(y) == 3)
510 strncpy(x, y, 3); // no-warning
511}
512
513void strncpy_exactly_matching_buffer(char *y) {
514 char x[4];
515 strncpy(x, y, 4); // no-warning
516
517 // strncpy does not null-terminate, so we have no idea what the strlen is
518 // after this.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000519 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
Jordy Rose5e5f1502011-06-20 03:49:16 +0000520}
521
Jordy Rose6e4244e2012-05-14 17:58:35 +0000522void strncpy_zero(char *src) {
523 char dst[] = "123";
524 strncpy(dst, src, 0); // no-warning
525}
526
527void strncpy_empty() {
528 char dst[] = "123";
529 char src[] = "";
530 strncpy(dst, src, 4); // no-warning
531}
532
Jordy Rose5e5f1502011-06-20 03:49:16 +0000533//===----------------------------------------------------------------------===
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000534// strncat()
535//===----------------------------------------------------------------------===
536
537#ifdef VARIANT
538
539#define __strncat_chk BUILTIN(__strncat_chk)
540char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
541
542#define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
543
544#else /* VARIANT */
545
546#define strncat BUILTIN(strncat)
547char *strncat(char *restrict s1, const char *restrict s2, size_t n);
548
549#endif /* VARIANT */
550
551
552void strncat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000553 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000554}
555
556void strncat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000557 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000558}
559
560void strncat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000561 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 +0000562}
563
564void strncat_effects(char *y) {
565 char x[8] = "123";
566 size_t orig_len = strlen(x);
567 char a = x[0];
568
569 if (strlen(y) != 4)
570 return;
571
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000572 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
573 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000574}
575
576void strncat_overflow_0(char *y) {
577 char x[4] = "12";
578 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000579 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 +0000580}
581
582void strncat_overflow_1(char *y) {
583 char x[4] = "12";
584 if (strlen(y) == 3)
Jordy Rose8912aae2011-06-20 21:55:40 +0000585 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 +0000586}
587
588void strncat_overflow_2(char *y) {
589 char x[4] = "12";
590 if (strlen(y) == 2)
Jordy Rose8912aae2011-06-20 21:55:40 +0000591 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 +0000592}
593
594void strncat_overflow_3(char *y) {
595 char x[4] = "12";
596 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000597 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 +0000598}
599void strncat_no_overflow_1(char *y) {
600 char x[5] = "12";
601 if (strlen(y) == 2)
602 strncat(x, y, strlen(y)); // no-warning
603}
604
605void strncat_no_overflow_2(char *y) {
606 char x[4] = "12";
607 if (strlen(y) == 4)
608 strncat(x, y, 1); // no-warning
609}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000610
Jordy Rose8912aae2011-06-20 21:55:40 +0000611void strncat_symbolic_dst_length(char *dst) {
612 strncat(dst, "1234", 5);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000613 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000614}
615
616void strncat_symbolic_src_length(char *src) {
617 char dst[8] = "1234";
618 strncat(dst, src, 3);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000619 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000620
621 char dst2[8] = "1234";
622 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
623}
624
625void strncat_unknown_src_length(char *src, int offset) {
626 char dst[8] = "1234";
627 strncat(dst, &src[offset], 3);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000628 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000629
630 char dst2[8] = "1234";
631 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
632}
633
634// There is no strncat_unknown_dst_length because if we can't get a symbolic
635// length for the "before" strlen, we won't be able to set one for "after".
636
637void strncat_symbolic_limit(unsigned limit) {
638 char dst[6] = "1234";
639 char src[] = "567";
640 strncat(dst, src, limit); // no-warning
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000641
642 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
643 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000644}
645
646void strncat_unknown_limit(float limit) {
647 char dst[6] = "1234";
648 char src[] = "567";
649 strncat(dst, src, (size_t)limit); // no-warning
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000650
651 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
652 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000653}
654
655void strncat_too_big(char *dst, char *src) {
656 if (strlen(dst) != (((size_t)0) - 2))
657 return;
658 if (strlen(src) != 2)
659 return;
660 strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
661}
662
Jordy Rose6e4244e2012-05-14 17:58:35 +0000663void strncat_zero(char *src) {
664 char dst[] = "123";
665 strncat(dst, src, 0); // no-warning
666}
667
668void strncat_empty() {
669 char dst[8] = "123";
670 char src[] = "";
671 strncat(dst, src, 4); // no-warning
672}
673
Lenny Maiorani318dd922011-04-12 17:08:43 +0000674//===----------------------------------------------------------------------===
675// strcmp()
676//===----------------------------------------------------------------------===
677
678#define strcmp BUILTIN(strcmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000679int strcmp(const char * s1, const char * s2);
Lenny Maiorani318dd922011-04-12 17:08:43 +0000680
681void strcmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000682 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000683}
684
685void strcmp_constant_and_var_0() {
686 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000687 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000688}
689
690void strcmp_constant_and_var_1() {
691 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000692 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000693}
694
695void strcmp_0() {
696 char *x = "123";
697 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000698 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000699}
700
701void strcmp_1() {
702 char *x = "234";
703 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000704 clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000705}
706
707void strcmp_2() {
708 char *x = "123";
709 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000710 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000711}
712
713void strcmp_null_0() {
714 char *x = NULL;
715 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000716 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000717}
718
719void strcmp_null_1() {
720 char *x = "123";
721 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000722 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000723}
724
725void strcmp_diff_length_0() {
726 char *x = "12345";
727 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000728 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000729}
730
731void strcmp_diff_length_1() {
732 char *x = "123";
733 char *y = "23456";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000734 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000735}
736
737void strcmp_diff_length_2() {
738 char *x = "12345";
739 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000740 clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000741}
742
743void strcmp_diff_length_3() {
744 char *x = "123";
745 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000746 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000747}
748
Jordy Roseadc42d42011-06-16 07:13:34 +0000749void strcmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000750 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000751}
752
753void strcmp_unknown_arg (char *unknown) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000754 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000755}
756
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000757//===----------------------------------------------------------------------===
758// strncmp()
759//===----------------------------------------------------------------------===
760
761#define strncmp BUILTIN(strncmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000762int strncmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000763
764void strncmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000765 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000766}
767
768void strncmp_constant_and_var_0() {
769 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000770 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000771}
772
773void strncmp_constant_and_var_1() {
774 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000775 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000776}
777
778void strncmp_0() {
779 char *x = "123";
780 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000781 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000782}
783
784void strncmp_1() {
785 char *x = "234";
786 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000787 clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000788}
789
790void strncmp_2() {
791 char *x = "123";
792 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000793 clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000794}
795
796void strncmp_null_0() {
797 char *x = NULL;
798 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000799 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000800}
801
802void strncmp_null_1() {
803 char *x = "123";
804 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000805 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000806}
807
808void strncmp_diff_length_0() {
809 char *x = "12345";
810 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000811 clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000812}
813
814void strncmp_diff_length_1() {
815 char *x = "123";
816 char *y = "23456";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000817 clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000818}
819
820void strncmp_diff_length_2() {
821 char *x = "12345";
822 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000823 clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000824}
825
826void strncmp_diff_length_3() {
827 char *x = "123";
828 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000829 clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000830}
831
832void strncmp_diff_length_4() {
833 char *x = "123";
834 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000835 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000836}
837
838void strncmp_diff_length_5() {
839 char *x = "012";
840 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000841 clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000842}
843
844void strncmp_diff_length_6() {
845 char *x = "234";
846 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000847 clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000848}
849
Jordy Roseadc42d42011-06-16 07:13:34 +0000850void strncmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000851 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000852}
853
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000854//===----------------------------------------------------------------------===
855// strcasecmp()
856//===----------------------------------------------------------------------===
857
858#define strcasecmp BUILTIN(strcasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000859int strcasecmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000860
861void strcasecmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000862 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000863}
864
865void strcasecmp_constant_and_var_0() {
866 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000867 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000868}
869
870void strcasecmp_constant_and_var_1() {
871 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000872 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000873}
874
875void strcasecmp_0() {
876 char *x = "abc";
877 char *y = "Abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000878 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000879}
880
881void strcasecmp_1() {
882 char *x = "Bcd";
883 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000884 clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000885}
886
887void strcasecmp_2() {
888 char *x = "abc";
889 char *y = "Bcd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000890 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000891}
892
893void strcasecmp_null_0() {
894 char *x = NULL;
895 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000896 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000897}
898
899void strcasecmp_null_1() {
900 char *x = "123";
901 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000902 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000903}
904
905void strcasecmp_diff_length_0() {
906 char *x = "abcde";
907 char *y = "aBd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000908 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000909}
910
911void strcasecmp_diff_length_1() {
912 char *x = "abc";
913 char *y = "aBdef";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000914 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000915}
916
917void strcasecmp_diff_length_2() {
918 char *x = "aBcDe";
919 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000920 clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000921}
922
923void strcasecmp_diff_length_3() {
924 char *x = "aBc";
925 char *y = "abcde";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000926 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000927}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000928
Jordy Roseadc42d42011-06-16 07:13:34 +0000929void strcasecmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000930 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000931}
932
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000933//===----------------------------------------------------------------------===
934// strncasecmp()
935//===----------------------------------------------------------------------===
936
937#define strncasecmp BUILTIN(strncasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000938int strncasecmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000939
940void strncasecmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000941 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000942}
943
944void strncasecmp_constant_and_var_0() {
945 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000946 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000947}
948
949void strncasecmp_constant_and_var_1() {
950 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000951 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000952}
953
954void strncasecmp_0() {
955 char *x = "abc";
956 char *y = "Abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000957 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000958}
959
960void strncasecmp_1() {
961 char *x = "Bcd";
962 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000963 clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000964}
965
966void strncasecmp_2() {
967 char *x = "abc";
968 char *y = "Bcd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000969 clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000970}
971
972void strncasecmp_null_0() {
973 char *x = NULL;
974 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000975 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000976}
977
978void strncasecmp_null_1() {
979 char *x = "123";
980 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000981 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000982}
983
984void strncasecmp_diff_length_0() {
985 char *x = "abcde";
986 char *y = "aBd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000987 clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000988}
989
990void strncasecmp_diff_length_1() {
991 char *x = "abc";
992 char *y = "aBdef";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000993 clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000994}
995
996void strncasecmp_diff_length_2() {
997 char *x = "aBcDe";
998 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000999 clang_analyzer_eval(strncasecmp(x, y, 5) == 1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001000}
1001
1002void strncasecmp_diff_length_3() {
1003 char *x = "aBc";
1004 char *y = "abcde";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001005 clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001006}
1007
1008void strncasecmp_diff_length_4() {
1009 char *x = "abcde";
1010 char *y = "aBc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001011 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001012}
1013
1014void strncasecmp_diff_length_5() {
1015 char *x = "abcde";
1016 char *y = "aBd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001017 clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001018}
1019
1020void strncasecmp_diff_length_6() {
1021 char *x = "aBDe";
1022 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001023 clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001024}
Jordy Roseadc42d42011-06-16 07:13:34 +00001025
1026void strncasecmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001027 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +00001028}
Anna Zaks74c0d692013-03-15 23:34:29 +00001029
1030//===----------------------------------------------------------------------===
1031// FIXMEs
1032//===----------------------------------------------------------------------===
1033
1034// The analyzer_eval call below should evaluate to true. We are being too
1035// aggressive in marking the (length of) src symbol dead. The length of dst
1036// depends on src. This could be explicitely specified in the checker or the
1037// logic for handling MetadataSymbol in SymbolManager needs to change.
1038void strcat_symbolic_src_length(char *src) {
1039 char dst[8] = "1234";
1040 strcat(dst, src);
1041 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
1042}
1043
1044// The analyzer_eval call below should evaluate to true. Most likely the same
1045// issue as the test above.
1046void strncpy_exactly_matching_buffer2(char *y) {
1047 if (strlen(y) >= 4)
1048 return;
1049
1050 char x[4];
1051 strncpy(x, y, 4); // no-warning
1052
1053 // This time, we know that y fits in x anyway.
1054 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
1055}