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_check_modelling() {
    684   char *x = "aa";
    685   char *y = "a";
    686   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
    687   clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}}
    688   clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}}
    689 
    690   clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}}
    691   clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}}
    692   clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}}
    693 }
    694 
    695 void strcmp_constant0() {
    696   clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
    697 }
    698 
    699 void strcmp_constant_and_var_0() {
    700   char *x = "123";
    701   clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
    702 }
    703 
    704 void strcmp_constant_and_var_1() {
    705   char *x = "123";
    706   clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
    707 }
    708 
    709 void strcmp_0() {
    710   char *x = "123";
    711   char *y = "123";
    712   clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
    713 }
    714 
    715 void strcmp_1() {
    716   char *x = "234";
    717   char *y = "123";
    718   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
    719 }
    720 
    721 void strcmp_2() {
    722   char *x = "123";
    723   char *y = "234";
    724   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
    725 }
    726 
    727 void strcmp_null_0() {
    728   char *x = NULL;
    729   char *y = "123";
    730   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    731 }
    732 
    733 void strcmp_null_1() {
    734   char *x = "123";
    735   char *y = NULL;
    736   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    737 }
    738 
    739 void strcmp_diff_length_0() {
    740   char *x = "12345";
    741   char *y = "234";
    742   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
    743 }
    744 
    745 void strcmp_diff_length_1() {
    746   char *x = "123";
    747   char *y = "23456";
    748   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
    749 }
    750 
    751 void strcmp_diff_length_2() {
    752   char *x = "12345";
    753   char *y = "123";
    754   clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}}
    755 }
    756 
    757 void strcmp_diff_length_3() {
    758   char *x = "123";
    759   char *y = "12345";
    760   clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}}
    761 }
    762 
    763 void strcmp_embedded_null () {
    764 	clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
    765 }
    766 
    767 void strcmp_unknown_arg (char *unknown) {
    768 	clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
    769 }
    770 
    771 union argument {
    772    char *f;
    773 };
    774 
    775 void function_pointer_cast_helper(char **a) {
    776   strcmp("Hi", *a); // PR24951 crash
    777 }
    778 
    779 void strcmp_union_function_pointer_cast(union argument a) {
    780   void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper;
    781 
    782   fPtr(&a);
    783 }
    784 
    785 //===----------------------------------------------------------------------===
    786 // strncmp()
    787 //===----------------------------------------------------------------------===
    788 
    789 #define strncmp BUILTIN(strncmp)
    790 int strncmp(const char *s1, const char *s2, size_t n);
    791 
    792 void strncmp_check_modelling() {
    793   char *x = "aa";
    794   char *y = "a";
    795   clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}}
    796   clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}}
    797   clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}}
    798 
    799   clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}}
    800   clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}}
    801   clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}}
    802 }
    803 
    804 void strncmp_constant0() {
    805   clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
    806 }
    807 
    808 void strncmp_constant_and_var_0() {
    809   char *x = "123";
    810   clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
    811 }
    812 
    813 void strncmp_constant_and_var_1() {
    814   char *x = "123";
    815   clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
    816 }
    817 
    818 void strncmp_0() {
    819   char *x = "123";
    820   char *y = "123";
    821   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    822 }
    823 
    824 void strncmp_1() {
    825   char *x = "234";
    826   char *y = "123";
    827   clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}}
    828 }
    829 
    830 void strncmp_2() {
    831   char *x = "123";
    832   char *y = "234";
    833   clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}}
    834 }
    835 
    836 void strncmp_null_0() {
    837   char *x = NULL;
    838   char *y = "123";
    839   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    840 }
    841 
    842 void strncmp_null_1() {
    843   char *x = "123";
    844   char *y = NULL;
    845   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    846 }
    847 
    848 void strncmp_diff_length_0() {
    849   char *x = "12345";
    850   char *y = "234";
    851   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
    852 }
    853 
    854 void strncmp_diff_length_1() {
    855   char *x = "123";
    856   char *y = "23456";
    857   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
    858 }
    859 
    860 void strncmp_diff_length_2() {
    861   char *x = "12345";
    862   char *y = "123";
    863   clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}}
    864 }
    865 
    866 void strncmp_diff_length_3() {
    867   char *x = "123";
    868   char *y = "12345";
    869   clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}}
    870 }
    871 
    872 void strncmp_diff_length_4() {
    873   char *x = "123";
    874   char *y = "12345";
    875   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    876 }
    877 
    878 void strncmp_diff_length_5() {
    879   char *x = "012";
    880   char *y = "12345";
    881   clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}}
    882 }
    883 
    884 void strncmp_diff_length_6() {
    885   char *x = "234";
    886   char *y = "12345";
    887   clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}}
    888 }
    889 
    890 void strncmp_embedded_null () {
    891 	clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
    892 }
    893 
    894 //===----------------------------------------------------------------------===
    895 // strcasecmp()
    896 //===----------------------------------------------------------------------===
    897 
    898 #define strcasecmp BUILTIN(strcasecmp)
    899 int strcasecmp(const char *s1, const char *s2);
    900 
    901 void strcasecmp_check_modelling() {
    902   char *x = "aa";
    903   char *y = "a";
    904   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
    905   clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}}
    906   clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}}
    907 
    908   clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}}
    909   clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}}
    910   clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}}
    911 }
    912 
    913 void strcasecmp_constant0() {
    914   clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
    915 }
    916 
    917 void strcasecmp_constant_and_var_0() {
    918   char *x = "abc";
    919   clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
    920 }
    921 
    922 void strcasecmp_constant_and_var_1() {
    923   char *x = "abc";
    924   clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
    925 }
    926 
    927 void strcasecmp_0() {
    928   char *x = "abc";
    929   char *y = "Abc";
    930   clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
    931 }
    932 
    933 void strcasecmp_1() {
    934   char *x = "Bcd";
    935   char *y = "abc";
    936   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
    937 }
    938 
    939 void strcasecmp_2() {
    940   char *x = "abc";
    941   char *y = "Bcd";
    942   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
    943 }
    944 
    945 void strcasecmp_null_0() {
    946   char *x = NULL;
    947   char *y = "123";
    948   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    949 }
    950 
    951 void strcasecmp_null_1() {
    952   char *x = "123";
    953   char *y = NULL;
    954   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    955 }
    956 
    957 void strcasecmp_diff_length_0() {
    958   char *x = "abcde";
    959   char *y = "aBd";
    960   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
    961 }
    962 
    963 void strcasecmp_diff_length_1() {
    964   char *x = "abc";
    965   char *y = "aBdef";
    966   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
    967 }
    968 
    969 void strcasecmp_diff_length_2() {
    970   char *x = "aBcDe";
    971   char *y = "abc";
    972   clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}}
    973 }
    974 
    975 void strcasecmp_diff_length_3() {
    976   char *x = "aBc";
    977   char *y = "abcde";
    978   clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}}
    979 }
    980 
    981 void strcasecmp_embedded_null () {
    982 	clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
    983 }
    984 
    985 //===----------------------------------------------------------------------===
    986 // strncasecmp()
    987 //===----------------------------------------------------------------------===
    988 
    989 #define strncasecmp BUILTIN(strncasecmp)
    990 int strncasecmp(const char *s1, const char *s2, size_t n);
    991 
    992 void strncasecmp_check_modelling() {
    993   char *x = "aa";
    994   char *y = "a";
    995   clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}}
    996   clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}}
    997   clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}}
    998 
    999   clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}}
   1000   clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}}
   1001   clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}}
   1002 }
   1003 
   1004 void strncasecmp_constant0() {
   1005   clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
   1006 }
   1007 
   1008 void strncasecmp_constant_and_var_0() {
   1009   char *x = "abc";
   1010   clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
   1011 }
   1012 
   1013 void strncasecmp_constant_and_var_1() {
   1014   char *x = "abc";
   1015   clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
   1016 }
   1017 
   1018 void strncasecmp_0() {
   1019   char *x = "abc";
   1020   char *y = "Abc";
   1021   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
   1022 }
   1023 
   1024 void strncasecmp_1() {
   1025   char *x = "Bcd";
   1026   char *y = "abc";
   1027   clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}}
   1028 }
   1029 
   1030 void strncasecmp_2() {
   1031   char *x = "abc";
   1032   char *y = "Bcd";
   1033   clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}}
   1034 }
   1035 
   1036 void strncasecmp_null_0() {
   1037   char *x = NULL;
   1038   char *y = "123";
   1039   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
   1040 }
   1041 
   1042 void strncasecmp_null_1() {
   1043   char *x = "123";
   1044   char *y = NULL;
   1045   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
   1046 }
   1047 
   1048 void strncasecmp_diff_length_0() {
   1049   char *x = "abcde";
   1050   char *y = "aBd";
   1051   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
   1052 }
   1053 
   1054 void strncasecmp_diff_length_1() {
   1055   char *x = "abc";
   1056   char *y = "aBdef";
   1057   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
   1058 }
   1059 
   1060 void strncasecmp_diff_length_2() {
   1061   char *x = "aBcDe";
   1062   char *y = "abc";
   1063   clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}}
   1064 }
   1065 
   1066 void strncasecmp_diff_length_3() {
   1067   char *x = "aBc";
   1068   char *y = "abcde";
   1069   clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}}
   1070 }
   1071 
   1072 void strncasecmp_diff_length_4() {
   1073   char *x = "abcde";
   1074   char *y = "aBc";
   1075   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
   1076 }
   1077 
   1078 void strncasecmp_diff_length_5() {
   1079   char *x = "abcde";
   1080   char *y = "aBd";
   1081   clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}}
   1082 }
   1083 
   1084 void strncasecmp_diff_length_6() {
   1085   char *x = "aBDe";
   1086   char *y = "abc";
   1087   clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}}
   1088 }
   1089 
   1090 void strncasecmp_embedded_null () {
   1091 	clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
   1092 }
   1093 
   1094 //===----------------------------------------------------------------------===
   1095 // strsep()
   1096 //===----------------------------------------------------------------------===
   1097 
   1098 char *strsep(char **stringp, const char *delim);
   1099 
   1100 void strsep_null_delim(char *s) {
   1101   strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}}
   1102 }
   1103 
   1104 void strsep_null_search() {
   1105   strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}}
   1106 }
   1107 
   1108 void strsep_return_original_pointer(char *s) {
   1109   char *original = s;
   1110   char *result = strsep(&s, ""); // no-warning
   1111   clang_analyzer_eval(original == result); // expected-warning{{TRUE}}
   1112 }
   1113 
   1114 void strsep_null_string() {
   1115   char *s = NULL;
   1116   char *result = strsep(&s, ""); // no-warning
   1117   clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}}
   1118 }
   1119 
   1120 void strsep_changes_input_pointer(char *s) {
   1121   char *original = s;
   1122   strsep(&s, ""); // no-warning
   1123   clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}}
   1124   clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}}
   1125 
   1126   // Check that the value is symbolic.
   1127   if (s == NULL) {
   1128     clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}}
   1129   }
   1130 }
   1131 
   1132 void strsep_changes_input_string() {
   1133   char str[] = "abc";
   1134 
   1135   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}}
   1136 
   1137   char *s = str;
   1138   strsep(&s, "b"); // no-warning
   1139 
   1140   // The real strsep will change the first delimiter it finds into a NUL
   1141   // character. For now, we just model the invalidation.
   1142   clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}}
   1143 }
   1144 
   1145 //===----------------------------------------------------------------------===
   1146 // FIXMEs
   1147 //===----------------------------------------------------------------------===
   1148 
   1149 // The analyzer_eval call below should evaluate to true. We are being too
   1150 // aggressive in marking the (length of) src symbol dead. The length of dst
   1151 // depends on src. This could be explicitely specified in the checker or the
   1152 // logic for handling MetadataSymbol in SymbolManager needs to change.
   1153 void strcat_symbolic_src_length(char *src) {
   1154 	char dst[8] = "1234";
   1155 	strcat(dst, src);
   1156   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
   1157 }
   1158 
   1159 // The analyzer_eval call below should evaluate to true. Most likely the same
   1160 // issue as the test above.
   1161 void strncpy_exactly_matching_buffer2(char *y) {
   1162 	if (strlen(y) >= 4)
   1163 		return;
   1164 
   1165 	char x[4];
   1166 	strncpy(x, y, 4); // no-warning
   1167 
   1168 	// This time, we know that y fits in x anyway.
   1169   clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
   1170 }
   1171