blob: 17a93ec013ae2230503116a7aaebf4641db53373 [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
Jordy Rosee64f3112010-08-16 07:51:42 +0000282void strcpy_effects(char *x, char *y) {
283 char a = x[0];
284
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000285 clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
286 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
287 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000288}
289
290void strcpy_overflow(char *y) {
291 char x[4];
292 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000293 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000294}
295
296void strcpy_no_overflow(char *y) {
297 char x[4];
298 if (strlen(y) == 3)
299 strcpy(x, y); // no-warning
300}
301
302//===----------------------------------------------------------------------===
303// stpcpy()
304//===----------------------------------------------------------------------===
305
306#ifdef VARIANT
307
308#define __stpcpy_chk BUILTIN(__stpcpy_chk)
309char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
310
311#define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1)
312
313#else /* VARIANT */
314
315#define stpcpy BUILTIN(stpcpy)
316char *stpcpy(char *restrict s1, const char *restrict s2);
317
318#endif /* VARIANT */
319
320
321void stpcpy_effect(char *x, char *y) {
322 char a = x[0];
323
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000324 clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}}
325 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
326 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000327}
328
329void stpcpy_overflow(char *y) {
330 char x[4];
331 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000332 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
Jordy Rosee64f3112010-08-16 07:51:42 +0000333}
334
335void stpcpy_no_overflow(char *y) {
336 char x[4];
337 if (strlen(y) == 3)
338 stpcpy(x, y); // no-warning
339}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000340
341//===----------------------------------------------------------------------===
342// strcat()
343//===----------------------------------------------------------------------===
344
345#ifdef VARIANT
346
347#define __strcat_chk BUILTIN(__strcat_chk)
348char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
349
350#define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
351
352#else /* VARIANT */
353
354#define strcat BUILTIN(strcat)
355char *strcat(char *restrict s1, const char *restrict s2);
356
357#endif /* VARIANT */
358
359
360void strcat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000361 strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000362}
363
364void strcat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000365 strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000366}
367
368void strcat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000369 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 +0000370}
371
372void strcat_effects(char *y) {
373 char x[8] = "123";
374 size_t orig_len = strlen(x);
375 char a = x[0];
376
377 if (strlen(y) != 4)
378 return;
379
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000380 clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
381 clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000382}
383
384void strcat_overflow_0(char *y) {
385 char x[4] = "12";
386 if (strlen(y) == 4)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000387 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000388}
389
390void strcat_overflow_1(char *y) {
391 char x[4] = "12";
392 if (strlen(y) == 3)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000393 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000394}
395
396void strcat_overflow_2(char *y) {
397 char x[4] = "12";
398 if (strlen(y) == 2)
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000399 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000400}
401
402void strcat_no_overflow(char *y) {
403 char x[5] = "12";
404 if (strlen(y) == 2)
405 strcat(x, y); // no-warning
406}
407
Jordy Rosed5af0e12011-06-15 05:52:56 +0000408void strcat_symbolic_dst_length(char *dst) {
409 strcat(dst, "1234");
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000410 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rosed5af0e12011-06-15 05:52:56 +0000411}
412
Anna Zakse3d250e2011-12-11 18:43:40 +0000413void strcat_symbolic_dst_length_taint(char *dst) {
414 scanf("%s", dst); // Taint data.
415 strcat(dst, "1234");
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000416 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Anna Zakse3d250e2011-12-11 18:43:40 +0000417}
418
Jordy Rosed5af0e12011-06-15 05:52:56 +0000419void strcat_unknown_src_length(char *src, int offset) {
420 char dst[8] = "1234";
421 strcat(dst, &src[offset]);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000422 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rosed5af0e12011-06-15 05:52:56 +0000423}
424
425// There is no strcat_unknown_dst_length because if we can't get a symbolic
426// length for the "before" strlen, we won't be able to set one for "after".
427
428void strcat_too_big(char *dst, char *src) {
429 if (strlen(dst) != (((size_t)0) - 2))
430 return;
431 if (strlen(src) != 2)
432 return;
433 strcat(dst, src); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
434}
435
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000436
437//===----------------------------------------------------------------------===
Jordy Rose5e5f1502011-06-20 03:49:16 +0000438// strncpy()
439//===----------------------------------------------------------------------===
440
441#ifdef VARIANT
442
443#define __strncpy_chk BUILTIN(__strncpy_chk)
444char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
445
446#define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
447
448#else /* VARIANT */
449
450#define strncpy BUILTIN(strncpy)
451char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
452
453#endif /* VARIANT */
454
455
456void strncpy_null_dst(char *x) {
457 strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
458}
459
460void strncpy_null_src(char *x) {
461 strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
462}
463
464void strncpy_fn(char *x) {
465 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}}
466}
467
468void strncpy_effects(char *x, char *y) {
469 char a = x[0];
470
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000471 clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
472 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
473 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
Jordy Rose5e5f1502011-06-20 03:49:16 +0000474}
475
476void strncpy_overflow(char *y) {
477 char x[4];
478 if (strlen(y) == 4)
479 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
480}
481
482void strncpy_no_overflow(char *y) {
483 char x[4];
484 if (strlen(y) == 3)
485 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
486}
487
488void strncpy_no_overflow2(char *y, int n) {
489 if (n <= 4)
490 return;
491
492 char x[4];
493 if (strlen(y) == 3)
494 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
495}
496
497void strncpy_truncate(char *y) {
498 char x[4];
499 if (strlen(y) == 4)
500 strncpy(x, y, 3); // no-warning
501}
502
503void strncpy_no_truncate(char *y) {
504 char x[4];
505 if (strlen(y) == 3)
506 strncpy(x, y, 3); // no-warning
507}
508
509void strncpy_exactly_matching_buffer(char *y) {
510 char x[4];
511 strncpy(x, y, 4); // no-warning
512
513 // strncpy does not null-terminate, so we have no idea what the strlen is
514 // after this.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000515 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
Jordy Rose5e5f1502011-06-20 03:49:16 +0000516}
517
Jordy Rose6e4244e2012-05-14 17:58:35 +0000518void strncpy_zero(char *src) {
519 char dst[] = "123";
520 strncpy(dst, src, 0); // no-warning
521}
522
523void strncpy_empty() {
524 char dst[] = "123";
525 char src[] = "";
526 strncpy(dst, src, 4); // no-warning
527}
528
Jordy Rose5e5f1502011-06-20 03:49:16 +0000529//===----------------------------------------------------------------------===
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000530// strncat()
531//===----------------------------------------------------------------------===
532
533#ifdef VARIANT
534
535#define __strncat_chk BUILTIN(__strncat_chk)
536char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
537
538#define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
539
540#else /* VARIANT */
541
542#define strncat BUILTIN(strncat)
543char *strncat(char *restrict s1, const char *restrict s2, size_t n);
544
545#endif /* VARIANT */
546
547
548void strncat_null_dst(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000549 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000550}
551
552void strncat_null_src(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000553 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000554}
555
556void strncat_fn(char *x) {
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000557 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 +0000558}
559
560void strncat_effects(char *y) {
561 char x[8] = "123";
562 size_t orig_len = strlen(x);
563 char a = x[0];
564
565 if (strlen(y) != 4)
566 return;
567
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000568 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
569 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
Lenny Maiorani067bbd02011-04-09 15:12:58 +0000570}
571
572void strncat_overflow_0(char *y) {
573 char x[4] = "12";
574 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000575 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 +0000576}
577
578void strncat_overflow_1(char *y) {
579 char x[4] = "12";
580 if (strlen(y) == 3)
Jordy Rose8912aae2011-06-20 21:55:40 +0000581 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 +0000582}
583
584void strncat_overflow_2(char *y) {
585 char x[4] = "12";
586 if (strlen(y) == 2)
Jordy Rose8912aae2011-06-20 21:55:40 +0000587 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 +0000588}
589
590void strncat_overflow_3(char *y) {
591 char x[4] = "12";
592 if (strlen(y) == 4)
Jordy Rose8912aae2011-06-20 21:55:40 +0000593 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 +0000594}
595void strncat_no_overflow_1(char *y) {
596 char x[5] = "12";
597 if (strlen(y) == 2)
598 strncat(x, y, strlen(y)); // no-warning
599}
600
601void strncat_no_overflow_2(char *y) {
602 char x[4] = "12";
603 if (strlen(y) == 4)
604 strncat(x, y, 1); // no-warning
605}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000606
Jordy Rose8912aae2011-06-20 21:55:40 +0000607void strncat_symbolic_dst_length(char *dst) {
608 strncat(dst, "1234", 5);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000609 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000610}
611
612void strncat_symbolic_src_length(char *src) {
613 char dst[8] = "1234";
614 strncat(dst, src, 3);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000615 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000616
617 char dst2[8] = "1234";
618 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
619}
620
621void strncat_unknown_src_length(char *src, int offset) {
622 char dst[8] = "1234";
623 strncat(dst, &src[offset], 3);
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000624 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000625
626 char dst2[8] = "1234";
627 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
628}
629
630// There is no strncat_unknown_dst_length because if we can't get a symbolic
631// length for the "before" strlen, we won't be able to set one for "after".
632
633void strncat_symbolic_limit(unsigned limit) {
634 char dst[6] = "1234";
635 char src[] = "567";
636 strncat(dst, src, limit); // no-warning
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000637
638 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
639 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000640}
641
642void strncat_unknown_limit(float limit) {
643 char dst[6] = "1234";
644 char src[] = "567";
645 strncat(dst, src, (size_t)limit); // no-warning
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000646
647 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
648 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
Jordy Rose8912aae2011-06-20 21:55:40 +0000649}
650
651void strncat_too_big(char *dst, char *src) {
652 if (strlen(dst) != (((size_t)0) - 2))
653 return;
654 if (strlen(src) != 2)
655 return;
656 strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}}
657}
658
Jordy Rose6e4244e2012-05-14 17:58:35 +0000659void strncat_zero(char *src) {
660 char dst[] = "123";
661 strncat(dst, src, 0); // no-warning
662}
663
664void strncat_empty() {
665 char dst[8] = "123";
666 char src[] = "";
667 strncat(dst, src, 4); // no-warning
668}
669
Lenny Maiorani318dd922011-04-12 17:08:43 +0000670//===----------------------------------------------------------------------===
671// strcmp()
672//===----------------------------------------------------------------------===
673
674#define strcmp BUILTIN(strcmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000675int strcmp(const char * s1, const char * s2);
Lenny Maiorani318dd922011-04-12 17:08:43 +0000676
677void strcmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000678 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000679}
680
681void strcmp_constant_and_var_0() {
682 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000683 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000684}
685
686void strcmp_constant_and_var_1() {
687 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000688 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000689}
690
691void strcmp_0() {
692 char *x = "123";
693 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000694 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000695}
696
697void strcmp_1() {
698 char *x = "234";
699 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000700 clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000701}
702
703void strcmp_2() {
704 char *x = "123";
705 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000706 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000707}
708
709void strcmp_null_0() {
710 char *x = NULL;
711 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000712 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000713}
714
715void strcmp_null_1() {
716 char *x = "123";
717 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000718 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000719}
720
721void strcmp_diff_length_0() {
722 char *x = "12345";
723 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000724 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000725}
726
727void strcmp_diff_length_1() {
728 char *x = "123";
729 char *y = "23456";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000730 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000731}
732
733void strcmp_diff_length_2() {
734 char *x = "12345";
735 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000736 clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000737}
738
739void strcmp_diff_length_3() {
740 char *x = "123";
741 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000742 clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maiorani318dd922011-04-12 17:08:43 +0000743}
744
Jordy Roseadc42d42011-06-16 07:13:34 +0000745void strcmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000746 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000747}
748
749void strcmp_unknown_arg (char *unknown) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000750 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000751}
752
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000753//===----------------------------------------------------------------------===
754// strncmp()
755//===----------------------------------------------------------------------===
756
757#define strncmp BUILTIN(strncmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000758int strncmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000759
760void strncmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000761 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000762}
763
764void strncmp_constant_and_var_0() {
765 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000766 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000767}
768
769void strncmp_constant_and_var_1() {
770 char *x = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000771 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000772}
773
774void strncmp_0() {
775 char *x = "123";
776 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000777 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000778}
779
780void strncmp_1() {
781 char *x = "234";
782 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000783 clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000784}
785
786void strncmp_2() {
787 char *x = "123";
788 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000789 clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000790}
791
792void strncmp_null_0() {
793 char *x = NULL;
794 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000795 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000796}
797
798void strncmp_null_1() {
799 char *x = "123";
800 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000801 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000802}
803
804void strncmp_diff_length_0() {
805 char *x = "12345";
806 char *y = "234";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000807 clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000808}
809
810void strncmp_diff_length_1() {
811 char *x = "123";
812 char *y = "23456";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000813 clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000814}
815
816void strncmp_diff_length_2() {
817 char *x = "12345";
818 char *y = "123";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000819 clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000820}
821
822void strncmp_diff_length_3() {
823 char *x = "123";
824 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000825 clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000826}
827
828void strncmp_diff_length_4() {
829 char *x = "123";
830 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000831 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000832}
833
834void strncmp_diff_length_5() {
835 char *x = "012";
836 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000837 clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000838}
839
840void strncmp_diff_length_6() {
841 char *x = "234";
842 char *y = "12345";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000843 clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani357f6ee2011-04-25 22:21:00 +0000844}
845
Jordy Roseadc42d42011-06-16 07:13:34 +0000846void strncmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000847 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000848}
849
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000850//===----------------------------------------------------------------------===
851// strcasecmp()
852//===----------------------------------------------------------------------===
853
854#define strcasecmp BUILTIN(strcasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000855int strcasecmp(const char *s1, const char *s2);
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000856
857void strcasecmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000858 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000859}
860
861void strcasecmp_constant_and_var_0() {
862 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000863 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000864}
865
866void strcasecmp_constant_and_var_1() {
867 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000868 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000869}
870
871void strcasecmp_0() {
872 char *x = "abc";
873 char *y = "Abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000874 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000875}
876
877void strcasecmp_1() {
878 char *x = "Bcd";
879 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000880 clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000881}
882
883void strcasecmp_2() {
884 char *x = "abc";
885 char *y = "Bcd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000886 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000887}
888
889void strcasecmp_null_0() {
890 char *x = NULL;
891 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000892 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000893}
894
895void strcasecmp_null_1() {
896 char *x = "123";
897 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000898 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000899}
900
901void strcasecmp_diff_length_0() {
902 char *x = "abcde";
903 char *y = "aBd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000904 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000905}
906
907void strcasecmp_diff_length_1() {
908 char *x = "abc";
909 char *y = "aBdef";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000910 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000911}
912
913void strcasecmp_diff_length_2() {
914 char *x = "aBcDe";
915 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000916 clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000917}
918
919void strcasecmp_diff_length_3() {
920 char *x = "aBc";
921 char *y = "abcde";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000922 clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
Lenny Maioranibd1d16a2011-04-28 15:09:11 +0000923}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000924
Jordy Roseadc42d42011-06-16 07:13:34 +0000925void strcasecmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000926 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +0000927}
928
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000929//===----------------------------------------------------------------------===
930// strncasecmp()
931//===----------------------------------------------------------------------===
932
933#define strncasecmp BUILTIN(strncasecmp)
Jordy Roseadc42d42011-06-16 07:13:34 +0000934int strncasecmp(const char *s1, const char *s2, size_t n);
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000935
936void strncasecmp_constant0() {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000937 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000938}
939
940void strncasecmp_constant_and_var_0() {
941 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000942 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000943}
944
945void strncasecmp_constant_and_var_1() {
946 char *x = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000947 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000948}
949
950void strncasecmp_0() {
951 char *x = "abc";
952 char *y = "Abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000953 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000954}
955
956void strncasecmp_1() {
957 char *x = "Bcd";
958 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000959 clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000960}
961
962void strncasecmp_2() {
963 char *x = "abc";
964 char *y = "Bcd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000965 clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000966}
967
968void strncasecmp_null_0() {
969 char *x = NULL;
970 char *y = "123";
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000971 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000972}
973
974void strncasecmp_null_1() {
975 char *x = "123";
976 char *y = NULL;
Jordy Rose9e49d9f2011-06-20 02:06:40 +0000977 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000978}
979
980void strncasecmp_diff_length_0() {
981 char *x = "abcde";
982 char *y = "aBd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000983 clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000984}
985
986void strncasecmp_diff_length_1() {
987 char *x = "abc";
988 char *y = "aBdef";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000989 clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000990}
991
992void strncasecmp_diff_length_2() {
993 char *x = "aBcDe";
994 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000995 clang_analyzer_eval(strncasecmp(x, y, 5) == 1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +0000996}
997
998void strncasecmp_diff_length_3() {
999 char *x = "aBc";
1000 char *y = "abcde";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001001 clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001002}
1003
1004void strncasecmp_diff_length_4() {
1005 char *x = "abcde";
1006 char *y = "aBc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001007 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001008}
1009
1010void strncasecmp_diff_length_5() {
1011 char *x = "abcde";
1012 char *y = "aBd";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001013 clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001014}
1015
1016void strncasecmp_diff_length_6() {
1017 char *x = "aBDe";
1018 char *y = "abc";
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001019 clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
Lenny Maiorani454fd2d2011-05-02 19:05:49 +00001020}
Jordy Roseadc42d42011-06-16 07:13:34 +00001021
1022void strncasecmp_embedded_null () {
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001023 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
Jordy Roseadc42d42011-06-16 07:13:34 +00001024}
Anna Zaks74c0d692013-03-15 23:34:29 +00001025
1026//===----------------------------------------------------------------------===
1027// FIXMEs
1028//===----------------------------------------------------------------------===
1029
1030// The analyzer_eval call below should evaluate to true. We are being too
1031// aggressive in marking the (length of) src symbol dead. The length of dst
1032// depends on src. This could be explicitely specified in the checker or the
1033// logic for handling MetadataSymbol in SymbolManager needs to change.
1034void strcat_symbolic_src_length(char *src) {
1035 char dst[8] = "1234";
1036 strcat(dst, src);
1037 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
1038}
1039
1040// The analyzer_eval call below should evaluate to true. Most likely the same
1041// issue as the test above.
1042void strncpy_exactly_matching_buffer2(char *y) {
1043 if (strlen(y) >= 4)
1044 return;
1045
1046 char x[4];
1047 strncpy(x, y, 4); // no-warning
1048
1049 // This time, we know that y fits in x anyway.
1050 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
1051}