Home | History | Annotate | Download | only in Analysis
      1 // 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
      5 
      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 
     18 // Functions that have variants and are also available as builtins should be
     19 // 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 
     27 #define NULL 0
     28 typedef typeof(sizeof(int)) size_t;
     29 
     30 void clang_analyzer_eval(int);
     31 
     32 int scanf(const char *restrict format, ...);
     33 
     34 //===----------------------------------------------------------------------===
     35 // strlen()
     36 //===----------------------------------------------------------------------===
     37 
     38 #define strlen BUILTIN(strlen)
     39 size_t strlen(const char *s);
     40 
     41 void strlen_constant0() {
     42   clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}}
     43 }
     44 
     45 void strlen_constant1() {
     46   const char *a = "123";
     47   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
     48 }
     49 
     50 void strlen_constant2(char x) {
     51   char a[] = "123";
     52   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
     53 
     54   a[0] = x;
     55   clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
     56 }
     57 
     58 size_t strlen_null() {
     59   return strlen(0); // expected-warning{{Null pointer argument in call to string length function}}
     60 }
     61 
     62 size_t strlen_fn() {
     63   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}}
     64 }
     65 
     66 size_t strlen_nonloc() {
     67 label:
     68   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}}
     69 }
     70 
     71 void strlen_subregion() {
     72   struct two_strings { char a[2], b[2]; };
     73   extern void use_two_strings(struct two_strings *);
     74 
     75   struct two_strings z;
     76   use_two_strings(&z);
     77 
     78   size_t a = strlen(z.a);
     79   z.b[0] = 5;
     80   size_t b = strlen(z.a);
     81   if (a == 0)
     82     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
     83 
     84   use_two_strings(&z);
     85 
     86   size_t c = strlen(z.a);
     87   if (a == 0)
     88     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
     89 }
     90 
     91 extern void use_string(char *);
     92 void strlen_argument(char *x) {
     93   size_t a = strlen(x);
     94   size_t b = strlen(x);
     95   if (a == 0)
     96     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
     97 
     98   use_string(x);
     99 
    100   size_t c = strlen(x);
    101   if (a == 0)
    102     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
    103 }
    104 
    105 extern char global_str[];
    106 void strlen_global() {
    107   size_t a = strlen(global_str);
    108   size_t b = strlen(global_str);
    109   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   }
    114 
    115   // Call a function with unknown effects, which should invalidate globals.
    116   use_string(0);
    117 
    118   size_t c = strlen(global_str);
    119   if (a == 0)
    120     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
    121 }
    122 
    123 void strlen_indirect(char *x) {
    124   size_t a = strlen(x);
    125   char *p = x;
    126   char **p2 = &p;
    127   size_t b = strlen(x);
    128   if (a == 0)
    129     clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
    130 
    131   extern void use_string_ptr(char*const*);
    132   use_string_ptr(p2);
    133 
    134   size_t c = strlen(x);
    135   if (a == 0)
    136     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
    137 }
    138 
    139 void 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);
    147   if (a == 0)
    148     clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
    149 }
    150 
    151 void strlen_liveness(const char *x) {
    152   if (strlen(x) < 5)
    153     return;
    154   clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
    155 }
    156 
    157 //===----------------------------------------------------------------------===
    158 // strnlen()
    159 //===----------------------------------------------------------------------===
    160 
    161 size_t strnlen(const char *s, size_t maxlen);
    162 
    163 void strnlen_constant0() {
    164   clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}}
    165 }
    166 
    167 void strnlen_constant1() {
    168   const char *a = "123";
    169   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
    170 }
    171 
    172 void strnlen_constant2(char x) {
    173   char a[] = "123";
    174   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
    175   a[0] = x;
    176   clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}
    177 }
    178 
    179 void strnlen_constant4() {
    180   clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}}
    181 }
    182 
    183 void strnlen_constant5() {
    184   const char *a = "123456";
    185   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
    186 }
    187 
    188 void strnlen_constant6(char x) {
    189   char a[] = "123456";
    190   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
    191   a[0] = x;
    192   clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}
    193 }
    194 
    195 size_t strnlen_null() {
    196   return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}}
    197 }
    198 
    199 size_t strnlen_fn() {
    200   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}}
    201 }
    202 
    203 size_t strnlen_nonloc() {
    204 label:
    205   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}}
    206 }
    207 
    208 void strnlen_zero() {
    209   clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}}
    210   clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}}
    211 }
    212 
    213 size_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 
    219 size_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 
    224 void strnlen_is_not_strlen(char *x) {
    225   clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}}
    226 }
    227 
    228 void strnlen_at_limit(char *x) {
    229   size_t len = strnlen(x, 10);
    230   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}}
    233 }
    234 
    235 void strnlen_at_actual(size_t limit) {
    236   size_t len = strnlen("abc", limit);
    237   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   }
    245 }
    246 
    247 //===----------------------------------------------------------------------===
    248 // strcpy()
    249 //===----------------------------------------------------------------------===
    250 
    251 #ifdef VARIANT
    252 
    253 #define __strcpy_chk BUILTIN(__strcpy_chk)
    254 char *__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)
    261 char *strcpy(char *restrict s1, const char *restrict s2);
    262 
    263 #endif /* VARIANT */
    264 
    265 
    266 void strcpy_null_dst(char *x) {
    267   strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
    268 }
    269 
    270 void strcpy_null_src(char *x) {
    271   strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
    272 }
    273 
    274 void strcpy_fn(char *x) {
    275   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}}
    276 }
    277 
    278 void 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 
    282 extern int globalInt;
    283 void strcpy_effects(char *x, char *y) {
    284   char a = x[0];
    285   if (globalInt != 42)
    286     return;
    287 
    288   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}}
    291   clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}
    292 }
    293 
    294 void strcpy_overflow(char *y) {
    295   char x[4];
    296   if (strlen(y) == 4)
    297     strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
    298 }
    299 
    300 void 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)
    313 char *__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)
    320 char *stpcpy(char *restrict s1, const char *restrict s2);
    321 
    322 #endif /* VARIANT */
    323 
    324 
    325 void stpcpy_effect(char *x, char *y) {
    326   char a = x[0];
    327 
    328   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}}
    331 }
    332 
    333 void stpcpy_overflow(char *y) {
    334   char x[4];
    335   if (strlen(y) == 4)
    336     stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
    337 }
    338 
    339 void stpcpy_no_overflow(char *y) {
    340   char x[4];
    341   if (strlen(y) == 3)
    342     stpcpy(x, y); // no-warning
    343 }
    344 
    345 //===----------------------------------------------------------------------===
    346 // strcat()
    347 //===----------------------------------------------------------------------===
    348 
    349 #ifdef VARIANT
    350 
    351 #define __strcat_chk BUILTIN(__strcat_chk)
    352 char *__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)
    359 char *strcat(char *restrict s1, const char *restrict s2);
    360 
    361 #endif /* VARIANT */
    362 
    363 
    364 void strcat_null_dst(char *x) {
    365   strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
    366 }
    367 
    368 void strcat_null_src(char *x) {
    369   strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
    370 }
    371 
    372 void strcat_fn(char *x) {
    373   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}}
    374 }
    375 
    376 void 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 
    384   clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
    385   clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
    386 }
    387 
    388 void strcat_overflow_0(char *y) {
    389   char x[4] = "12";
    390   if (strlen(y) == 4)
    391     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
    392 }
    393 
    394 void strcat_overflow_1(char *y) {
    395   char x[4] = "12";
    396   if (strlen(y) == 3)
    397     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
    398 }
    399 
    400 void strcat_overflow_2(char *y) {
    401   char x[4] = "12";
    402   if (strlen(y) == 2)
    403     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
    404 }
    405 
    406 void strcat_no_overflow(char *y) {
    407   char x[5] = "12";
    408   if (strlen(y) == 2)
    409     strcat(x, y); // no-warning
    410 }
    411 
    412 void strcat_symbolic_dst_length(char *dst) {
    413 	strcat(dst, "1234");
    414   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    415 }
    416 
    417 void strcat_symbolic_dst_length_taint(char *dst) {
    418   scanf("%s", dst); // Taint data.
    419   strcat(dst, "1234");
    420   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    421 }
    422 
    423 void strcat_unknown_src_length(char *src, int offset) {
    424 	char dst[8] = "1234";
    425 	strcat(dst, &src[offset]);
    426   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    427 }
    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 
    432 void strcat_too_big(char *dst, char *src) {
    433   // We assume this can never actually happen, so we don't get a warning.
    434 	if (strlen(dst) != (((size_t)0) - 2))
    435 		return;
    436 	if (strlen(src) != 2)
    437 		return;
    438 	strcat(dst, src);
    439 }
    440 
    441 
    442 //===----------------------------------------------------------------------===
    443 // strncpy()
    444 //===----------------------------------------------------------------------===
    445 
    446 #ifdef VARIANT
    447 
    448 #define __strncpy_chk BUILTIN(__strncpy_chk)
    449 char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
    450 
    451 #define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1)
    452 
    453 #else /* VARIANT */
    454 
    455 #define strncpy BUILTIN(strncpy)
    456 char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
    457 
    458 #endif /* VARIANT */
    459 
    460 
    461 void strncpy_null_dst(char *x) {
    462   strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
    463 }
    464 
    465 void strncpy_null_src(char *x) {
    466   strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
    467 }
    468 
    469 void strncpy_fn(char *x) {
    470   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}}
    471 }
    472 
    473 void strncpy_effects(char *x, char *y) {
    474   char a = x[0];
    475 
    476   clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
    477   clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
    478   clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
    479 }
    480 
    481 void strncpy_overflow(char *y) {
    482   char x[4];
    483   if (strlen(y) == 4)
    484     strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
    485 }
    486 
    487 void strncpy_no_overflow(char *y) {
    488   char x[4];
    489   if (strlen(y) == 3)
    490     strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
    491 }
    492 
    493 void strncpy_no_overflow2(char *y, int n) {
    494 	if (n <= 4)
    495 		return;
    496 
    497   char x[4];
    498   if (strlen(y) == 3)
    499     strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}}
    500 }
    501 
    502 void strncpy_truncate(char *y) {
    503   char x[4];
    504   if (strlen(y) == 4)
    505     strncpy(x, y, 3); // no-warning
    506 }
    507 
    508 void strncpy_no_truncate(char *y) {
    509   char x[4];
    510   if (strlen(y) == 3)
    511     strncpy(x, y, 3); // no-warning
    512 }
    513 
    514 void strncpy_exactly_matching_buffer(char *y) {
    515 	char x[4];
    516 	strncpy(x, y, 4); // no-warning
    517 
    518 	// strncpy does not null-terminate, so we have no idea what the strlen is
    519 	// after this.
    520   clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
    521 }
    522 
    523 void strncpy_zero(char *src) {
    524   char dst[] = "123";
    525   strncpy(dst, src, 0); // no-warning
    526 }
    527 
    528 void strncpy_empty() {
    529   char dst[] = "123";
    530   char src[] = "";
    531   strncpy(dst, src, 4); // no-warning
    532 }
    533 
    534 //===----------------------------------------------------------------------===
    535 // strncat()
    536 //===----------------------------------------------------------------------===
    537 
    538 #ifdef VARIANT
    539 
    540 #define __strncat_chk BUILTIN(__strncat_chk)
    541 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen);
    542 
    543 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1)
    544 
    545 #else /* VARIANT */
    546 
    547 #define strncat BUILTIN(strncat)
    548 char *strncat(char *restrict s1, const char *restrict s2, size_t n);
    549 
    550 #endif /* VARIANT */
    551 
    552 
    553 void strncat_null_dst(char *x) {
    554   strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
    555 }
    556 
    557 void strncat_null_src(char *x) {
    558   strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
    559 }
    560 
    561 void strncat_fn(char *x) {
    562   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}}
    563 }
    564 
    565 void strncat_effects(char *y) {
    566   char x[8] = "123";
    567   size_t orig_len = strlen(x);
    568   char a = x[0];
    569 
    570   if (strlen(y) != 4)
    571     return;
    572 
    573   clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
    574   clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
    575 }
    576 
    577 void strncat_overflow_0(char *y) {
    578   char x[4] = "12";
    579   if (strlen(y) == 4)
    580     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    581 }
    582 
    583 void strncat_overflow_1(char *y) {
    584   char x[4] = "12";
    585   if (strlen(y) == 3)
    586     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    587 }
    588 
    589 void strncat_overflow_2(char *y) {
    590   char x[4] = "12";
    591   if (strlen(y) == 2)
    592     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    593 }
    594 
    595 void strncat_overflow_3(char *y) {
    596   char x[4] = "12";
    597   if (strlen(y) == 4)
    598     strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    599 }
    600 void strncat_no_overflow_1(char *y) {
    601   char x[5] = "12";
    602   if (strlen(y) == 2)
    603     strncat(x, y, strlen(y)); // no-warning
    604 }
    605 
    606 void strncat_no_overflow_2(char *y) {
    607   char x[4] = "12";
    608   if (strlen(y) == 4)
    609     strncat(x, y, 1); // no-warning
    610 }
    611 
    612 void strncat_symbolic_dst_length(char *dst) {
    613   strncat(dst, "1234", 5);
    614   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    615 }
    616 
    617 void strncat_symbolic_src_length(char *src) {
    618   char dst[8] = "1234";
    619   strncat(dst, src, 3);
    620   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    621 
    622   char dst2[8] = "1234";
    623   strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    624 }
    625 
    626 void strncat_unknown_src_length(char *src, int offset) {
    627   char dst[8] = "1234";
    628   strncat(dst, &src[offset], 3);
    629   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    630 
    631   char dst2[8] = "1234";
    632   strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    633 }
    634 
    635 // There is no strncat_unknown_dst_length because if we can't get a symbolic
    636 // length for the "before" strlen, we won't be able to set one for "after".
    637 
    638 void strncat_symbolic_limit(unsigned limit) {
    639   char dst[6] = "1234";
    640   char src[] = "567";
    641   strncat(dst, src, limit); // no-warning
    642 
    643   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    644   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
    645 }
    646 
    647 void strncat_unknown_limit(float limit) {
    648   char dst[6] = "1234";
    649   char src[] = "567";
    650   strncat(dst, src, (size_t)limit); // no-warning
    651 
    652   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    653   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
    654 }
    655 
    656 void strncat_too_big(char *dst, char *src) {
    657   // We assume this will never actually happen, so we don't get a warning.
    658   if (strlen(dst) != (((size_t)0) - 2))
    659     return;
    660   if (strlen(src) != 2)
    661     return;
    662   strncat(dst, src, 2);
    663 }
    664 
    665 void strncat_zero(char *src) {
    666   char dst[] = "123";
    667   strncat(dst, src, 0); // no-warning
    668 }
    669 
    670 void strncat_empty() {
    671   char dst[8] = "123";
    672   char src[] = "";
    673   strncat(dst, src, 4); // no-warning
    674 }
    675 
    676 //===----------------------------------------------------------------------===
    677 // strcmp()
    678 //===----------------------------------------------------------------------===
    679 
    680 #define strcmp BUILTIN(strcmp)
    681 int strcmp(const char * s1, const char * s2);
    682 
    683 void strcmp_constant0() {
    684   clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
    685 }
    686 
    687 void strcmp_constant_and_var_0() {
    688   char *x = "123";
    689   clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
    690 }
    691 
    692 void strcmp_constant_and_var_1() {
    693   char *x = "123";
    694   clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
    695 }
    696 
    697 void strcmp_0() {
    698   char *x = "123";
    699   char *y = "123";
    700   clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
    701 }
    702 
    703 void strcmp_1() {
    704   char *x = "234";
    705   char *y = "123";
    706   clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
    707 }
    708 
    709 void strcmp_2() {
    710   char *x = "123";
    711   char *y = "234";
    712   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    713 }
    714 
    715 void strcmp_null_0() {
    716   char *x = NULL;
    717   char *y = "123";
    718   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    719 }
    720 
    721 void strcmp_null_1() {
    722   char *x = "123";
    723   char *y = NULL;
    724   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    725 }
    726 
    727 void strcmp_diff_length_0() {
    728   char *x = "12345";
    729   char *y = "234";
    730   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    731 }
    732 
    733 void strcmp_diff_length_1() {
    734   char *x = "123";
    735   char *y = "23456";
    736   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    737 }
    738 
    739 void strcmp_diff_length_2() {
    740   char *x = "12345";
    741   char *y = "123";
    742   clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
    743 }
    744 
    745 void strcmp_diff_length_3() {
    746   char *x = "123";
    747   char *y = "12345";
    748   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    749 }
    750 
    751 void strcmp_embedded_null () {
    752 	clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
    753 }
    754 
    755 void strcmp_unknown_arg (char *unknown) {
    756 	clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
    757 }
    758 
    759 //===----------------------------------------------------------------------===
    760 // strncmp()
    761 //===----------------------------------------------------------------------===
    762 
    763 #define strncmp BUILTIN(strncmp)
    764 int strncmp(const char *s1, const char *s2, size_t n);
    765 
    766 void strncmp_constant0() {
    767   clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
    768 }
    769 
    770 void strncmp_constant_and_var_0() {
    771   char *x = "123";
    772   clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
    773 }
    774 
    775 void strncmp_constant_and_var_1() {
    776   char *x = "123";
    777   clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
    778 }
    779 
    780 void strncmp_0() {
    781   char *x = "123";
    782   char *y = "123";
    783   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    784 }
    785 
    786 void strncmp_1() {
    787   char *x = "234";
    788   char *y = "123";
    789   clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
    790 }
    791 
    792 void strncmp_2() {
    793   char *x = "123";
    794   char *y = "234";
    795   clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
    796 }
    797 
    798 void strncmp_null_0() {
    799   char *x = NULL;
    800   char *y = "123";
    801   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    802 }
    803 
    804 void strncmp_null_1() {
    805   char *x = "123";
    806   char *y = NULL;
    807   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    808 }
    809 
    810 void strncmp_diff_length_0() {
    811   char *x = "12345";
    812   char *y = "234";
    813   clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    814 }
    815 
    816 void strncmp_diff_length_1() {
    817   char *x = "123";
    818   char *y = "23456";
    819   clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    820 }
    821 
    822 void strncmp_diff_length_2() {
    823   char *x = "12345";
    824   char *y = "123";
    825   clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}}
    826 }
    827 
    828 void strncmp_diff_length_3() {
    829   char *x = "123";
    830   char *y = "12345";
    831   clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    832 }
    833 
    834 void strncmp_diff_length_4() {
    835   char *x = "123";
    836   char *y = "12345";
    837   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    838 }
    839 
    840 void strncmp_diff_length_5() {
    841   char *x = "012";
    842   char *y = "12345";
    843   clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
    844 }
    845 
    846 void strncmp_diff_length_6() {
    847   char *x = "234";
    848   char *y = "12345";
    849   clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
    850 }
    851 
    852 void strncmp_embedded_null () {
    853 	clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
    854 }
    855 
    856 //===----------------------------------------------------------------------===
    857 // strcasecmp()
    858 //===----------------------------------------------------------------------===
    859 
    860 #define strcasecmp BUILTIN(strcasecmp)
    861 int strcasecmp(const char *s1, const char *s2);
    862 
    863 void strcasecmp_constant0() {
    864   clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
    865 }
    866 
    867 void strcasecmp_constant_and_var_0() {
    868   char *x = "abc";
    869   clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
    870 }
    871 
    872 void strcasecmp_constant_and_var_1() {
    873   char *x = "abc";
    874   clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
    875 }
    876 
    877 void strcasecmp_0() {
    878   char *x = "abc";
    879   char *y = "Abc";
    880   clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
    881 }
    882 
    883 void strcasecmp_1() {
    884   char *x = "Bcd";
    885   char *y = "abc";
    886   clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
    887 }
    888 
    889 void strcasecmp_2() {
    890   char *x = "abc";
    891   char *y = "Bcd";
    892   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    893 }
    894 
    895 void strcasecmp_null_0() {
    896   char *x = NULL;
    897   char *y = "123";
    898   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    899 }
    900 
    901 void strcasecmp_null_1() {
    902   char *x = "123";
    903   char *y = NULL;
    904   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    905 }
    906 
    907 void strcasecmp_diff_length_0() {
    908   char *x = "abcde";
    909   char *y = "aBd";
    910   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    911 }
    912 
    913 void strcasecmp_diff_length_1() {
    914   char *x = "abc";
    915   char *y = "aBdef";
    916   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    917 }
    918 
    919 void strcasecmp_diff_length_2() {
    920   char *x = "aBcDe";
    921   char *y = "abc";
    922   clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
    923 }
    924 
    925 void strcasecmp_diff_length_3() {
    926   char *x = "aBc";
    927   char *y = "abcde";
    928   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    929 }
    930 
    931 void strcasecmp_embedded_null () {
    932 	clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
    933 }
    934 
    935 //===----------------------------------------------------------------------===
    936 // strncasecmp()
    937 //===----------------------------------------------------------------------===
    938 
    939 #define strncasecmp BUILTIN(strncasecmp)
    940 int strncasecmp(const char *s1, const char *s2, size_t n);
    941 
    942 void strncasecmp_constant0() {
    943   clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
    944 }
    945 
    946 void strncasecmp_constant_and_var_0() {
    947   char *x = "abc";
    948   clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
    949 }
    950 
    951 void strncasecmp_constant_and_var_1() {
    952   char *x = "abc";
    953   clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
    954 }
    955 
    956 void strncasecmp_0() {
    957   char *x = "abc";
    958   char *y = "Abc";
    959   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    960 }
    961 
    962 void strncasecmp_1() {
    963   char *x = "Bcd";
    964   char *y = "abc";
    965   clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
    966 }
    967 
    968 void strncasecmp_2() {
    969   char *x = "abc";
    970   char *y = "Bcd";
    971   clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
    972 }
    973 
    974 void strncasecmp_null_0() {
    975   char *x = NULL;
    976   char *y = "123";
    977   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    978 }
    979 
    980 void strncasecmp_null_1() {
    981   char *x = "123";
    982   char *y = NULL;
    983   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    984 }
    985 
    986 void strncasecmp_diff_length_0() {
    987   char *x = "abcde";
    988   char *y = "aBd";
    989   clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    990 }
    991 
    992 void strncasecmp_diff_length_1() {
    993   char *x = "abc";
    994   char *y = "aBdef";
    995   clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    996 }
    997 
    998 void strncasecmp_diff_length_2() {
    999   char *x = "aBcDe";
   1000   char *y = "abc";
   1001   clang_analyzer_eval(strncasecmp(x, y, 5) == 1); // expected-warning{{TRUE}}
   1002 }
   1003 
   1004 void strncasecmp_diff_length_3() {
   1005   char *x = "aBc";
   1006   char *y = "abcde";
   1007   clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
   1008 }
   1009 
   1010 void strncasecmp_diff_length_4() {
   1011   char *x = "abcde";
   1012   char *y = "aBc";
   1013   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
   1014 }
   1015 
   1016 void strncasecmp_diff_length_5() {
   1017   char *x = "abcde";
   1018   char *y = "aBd";
   1019   clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
   1020 }
   1021 
   1022 void strncasecmp_diff_length_6() {
   1023   char *x = "aBDe";
   1024   char *y = "abc";
   1025   clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
   1026 }
   1027 
   1028 void strncasecmp_embedded_null () {
   1029 	clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
   1030 }
   1031 
   1032 //===----------------------------------------------------------------------===
   1033 // strsep()
   1034 //===----------------------------------------------------------------------===
   1035 
   1036 char *strsep(char **stringp, const char *delim);
   1037 
   1038 void strsep_null_delim(char *s) {
   1039   strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}}
   1040 }
   1041 
   1042 void strsep_null_search() {
   1043   strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}}
   1044 }
   1045 
   1046 void strsep_return_original_pointer(char *s) {
   1047   char *original = s;
   1048   char *result = strsep(&s, ""); // no-warning
   1049   clang_analyzer_eval(original == result); // expected-warning{{TRUE}}
   1050 }
   1051 
   1052 void strsep_null_string() {
   1053   char *s = NULL;
   1054   char *result = strsep(&s, ""); // no-warning
   1055   clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}}
   1056 }
   1057 
   1058 void strsep_changes_input_pointer(char *s) {
   1059   char *original = s;
   1060   strsep(&s, ""); // no-warning
   1061   clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}}
   1062   clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}}
   1063 
   1064   // Check that the value is symbolic.
   1065   if (s == NULL) {
   1066     clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}}
   1067   }
   1068 }
   1069 
   1070 void strsep_changes_input_string() {
   1071   char str[] = "abc";
   1072 
   1073   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}}
   1074 
   1075   char *s = str;
   1076   strsep(&s, "b"); // no-warning
   1077 
   1078   // The real strsep will change the first delimiter it finds into a NUL
   1079   // character. For now, we just model the invalidation.
   1080   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}}
   1081 }
   1082 
   1083 //===----------------------------------------------------------------------===
   1084 // FIXMEs
   1085 //===----------------------------------------------------------------------===
   1086 
   1087 // The analyzer_eval call below should evaluate to true. We are being too
   1088 // aggressive in marking the (length of) src symbol dead. The length of dst
   1089 // depends on src. This could be explicitely specified in the checker or the
   1090 // logic for handling MetadataSymbol in SymbolManager needs to change.
   1091 void strcat_symbolic_src_length(char *src) {
   1092 	char dst[8] = "1234";
   1093 	strcat(dst, src);
   1094   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
   1095 }
   1096 
   1097 // The analyzer_eval call below should evaluate to true. Most likely the same
   1098 // issue as the test above.
   1099 void strncpy_exactly_matching_buffer2(char *y) {
   1100 	if (strlen(y) >= 4)
   1101 		return;
   1102 
   1103 	char x[4];
   1104 	strncpy(x, y, 4); // no-warning
   1105 
   1106 	// This time, we know that y fits in x anyway.
   1107   clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
   1108 }
   1109