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 void strcpy_effects(char *x, char *y) {
    283   char a = x[0];
    284 
    285   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}}
    288 }
    289 
    290 void strcpy_overflow(char *y) {
    291   char x[4];
    292   if (strlen(y) == 4)
    293     strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
    294 }
    295 
    296 void 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)
    309 char *__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)
    316 char *stpcpy(char *restrict s1, const char *restrict s2);
    317 
    318 #endif /* VARIANT */
    319 
    320 
    321 void stpcpy_effect(char *x, char *y) {
    322   char a = x[0];
    323 
    324   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}}
    327 }
    328 
    329 void stpcpy_overflow(char *y) {
    330   char x[4];
    331   if (strlen(y) == 4)
    332     stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}}
    333 }
    334 
    335 void stpcpy_no_overflow(char *y) {
    336   char x[4];
    337   if (strlen(y) == 3)
    338     stpcpy(x, y); // no-warning
    339 }
    340 
    341 //===----------------------------------------------------------------------===
    342 // strcat()
    343 //===----------------------------------------------------------------------===
    344 
    345 #ifdef VARIANT
    346 
    347 #define __strcat_chk BUILTIN(__strcat_chk)
    348 char *__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)
    355 char *strcat(char *restrict s1, const char *restrict s2);
    356 
    357 #endif /* VARIANT */
    358 
    359 
    360 void strcat_null_dst(char *x) {
    361   strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}}
    362 }
    363 
    364 void strcat_null_src(char *x) {
    365   strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}}
    366 }
    367 
    368 void strcat_fn(char *x) {
    369   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}}
    370 }
    371 
    372 void 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 
    380   clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
    381   clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
    382 }
    383 
    384 void strcat_overflow_0(char *y) {
    385   char x[4] = "12";
    386   if (strlen(y) == 4)
    387     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
    388 }
    389 
    390 void strcat_overflow_1(char *y) {
    391   char x[4] = "12";
    392   if (strlen(y) == 3)
    393     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
    394 }
    395 
    396 void strcat_overflow_2(char *y) {
    397   char x[4] = "12";
    398   if (strlen(y) == 2)
    399     strcat(x, y); // expected-warning{{String copy function overflows destination buffer}}
    400 }
    401 
    402 void strcat_no_overflow(char *y) {
    403   char x[5] = "12";
    404   if (strlen(y) == 2)
    405     strcat(x, y); // no-warning
    406 }
    407 
    408 void strcat_symbolic_dst_length(char *dst) {
    409 	strcat(dst, "1234");
    410   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    411 }
    412 
    413 void strcat_symbolic_dst_length_taint(char *dst) {
    414   scanf("%s", dst); // Taint data.
    415   strcat(dst, "1234");
    416   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    417 }
    418 
    419 void strcat_unknown_src_length(char *src, int offset) {
    420 	char dst[8] = "1234";
    421 	strcat(dst, &src[offset]);
    422   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    423 }
    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 
    428 void 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 
    436 
    437 //===----------------------------------------------------------------------===
    438 // strncpy()
    439 //===----------------------------------------------------------------------===
    440 
    441 #ifdef VARIANT
    442 
    443 #define __strncpy_chk BUILTIN(__strncpy_chk)
    444 char *__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)
    451 char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
    452 
    453 #endif /* VARIANT */
    454 
    455 
    456 void strncpy_null_dst(char *x) {
    457   strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}}
    458 }
    459 
    460 void strncpy_null_src(char *x) {
    461   strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}}
    462 }
    463 
    464 void 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 
    468 void strncpy_effects(char *x, char *y) {
    469   char a = x[0];
    470 
    471   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}}
    474 }
    475 
    476 void 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 
    482 void 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 
    488 void 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 
    497 void strncpy_truncate(char *y) {
    498   char x[4];
    499   if (strlen(y) == 4)
    500     strncpy(x, y, 3); // no-warning
    501 }
    502 
    503 void strncpy_no_truncate(char *y) {
    504   char x[4];
    505   if (strlen(y) == 3)
    506     strncpy(x, y, 3); // no-warning
    507 }
    508 
    509 void 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.
    515   clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
    516 }
    517 
    518 void strncpy_zero(char *src) {
    519   char dst[] = "123";
    520   strncpy(dst, src, 0); // no-warning
    521 }
    522 
    523 void strncpy_empty() {
    524   char dst[] = "123";
    525   char src[] = "";
    526   strncpy(dst, src, 4); // no-warning
    527 }
    528 
    529 //===----------------------------------------------------------------------===
    530 // strncat()
    531 //===----------------------------------------------------------------------===
    532 
    533 #ifdef VARIANT
    534 
    535 #define __strncat_chk BUILTIN(__strncat_chk)
    536 char *__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)
    543 char *strncat(char *restrict s1, const char *restrict s2, size_t n);
    544 
    545 #endif /* VARIANT */
    546 
    547 
    548 void strncat_null_dst(char *x) {
    549   strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}}
    550 }
    551 
    552 void strncat_null_src(char *x) {
    553   strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}}
    554 }
    555 
    556 void strncat_fn(char *x) {
    557   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}}
    558 }
    559 
    560 void 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 
    568   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}}
    570 }
    571 
    572 void strncat_overflow_0(char *y) {
    573   char x[4] = "12";
    574   if (strlen(y) == 4)
    575     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    576 }
    577 
    578 void strncat_overflow_1(char *y) {
    579   char x[4] = "12";
    580   if (strlen(y) == 3)
    581     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    582 }
    583 
    584 void strncat_overflow_2(char *y) {
    585   char x[4] = "12";
    586   if (strlen(y) == 2)
    587     strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    588 }
    589 
    590 void strncat_overflow_3(char *y) {
    591   char x[4] = "12";
    592   if (strlen(y) == 4)
    593     strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
    594 }
    595 void 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 
    601 void strncat_no_overflow_2(char *y) {
    602   char x[4] = "12";
    603   if (strlen(y) == 4)
    604     strncat(x, y, 1); // no-warning
    605 }
    606 
    607 void strncat_symbolic_dst_length(char *dst) {
    608   strncat(dst, "1234", 5);
    609   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    610 }
    611 
    612 void strncat_symbolic_src_length(char *src) {
    613   char dst[8] = "1234";
    614   strncat(dst, src, 3);
    615   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    616 
    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 
    621 void strncat_unknown_src_length(char *src, int offset) {
    622   char dst[8] = "1234";
    623   strncat(dst, &src[offset], 3);
    624   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    625 
    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 
    633 void strncat_symbolic_limit(unsigned limit) {
    634   char dst[6] = "1234";
    635   char src[] = "567";
    636   strncat(dst, src, limit); // no-warning
    637 
    638   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    639   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
    640 }
    641 
    642 void strncat_unknown_limit(float limit) {
    643   char dst[6] = "1234";
    644   char src[] = "567";
    645   strncat(dst, src, (size_t)limit); // no-warning
    646 
    647   clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
    648   clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
    649 }
    650 
    651 void 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 
    659 void strncat_zero(char *src) {
    660   char dst[] = "123";
    661   strncat(dst, src, 0); // no-warning
    662 }
    663 
    664 void strncat_empty() {
    665   char dst[8] = "123";
    666   char src[] = "";
    667   strncat(dst, src, 4); // no-warning
    668 }
    669 
    670 //===----------------------------------------------------------------------===
    671 // strcmp()
    672 //===----------------------------------------------------------------------===
    673 
    674 #define strcmp BUILTIN(strcmp)
    675 int strcmp(const char * s1, const char * s2);
    676 
    677 void strcmp_constant0() {
    678   clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
    679 }
    680 
    681 void strcmp_constant_and_var_0() {
    682   char *x = "123";
    683   clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
    684 }
    685 
    686 void strcmp_constant_and_var_1() {
    687   char *x = "123";
    688   clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
    689 }
    690 
    691 void strcmp_0() {
    692   char *x = "123";
    693   char *y = "123";
    694   clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
    695 }
    696 
    697 void strcmp_1() {
    698   char *x = "234";
    699   char *y = "123";
    700   clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
    701 }
    702 
    703 void strcmp_2() {
    704   char *x = "123";
    705   char *y = "234";
    706   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    707 }
    708 
    709 void strcmp_null_0() {
    710   char *x = NULL;
    711   char *y = "123";
    712   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    713 }
    714 
    715 void strcmp_null_1() {
    716   char *x = "123";
    717   char *y = NULL;
    718   strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    719 }
    720 
    721 void strcmp_diff_length_0() {
    722   char *x = "12345";
    723   char *y = "234";
    724   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    725 }
    726 
    727 void strcmp_diff_length_1() {
    728   char *x = "123";
    729   char *y = "23456";
    730   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    731 }
    732 
    733 void strcmp_diff_length_2() {
    734   char *x = "12345";
    735   char *y = "123";
    736   clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
    737 }
    738 
    739 void strcmp_diff_length_3() {
    740   char *x = "123";
    741   char *y = "12345";
    742   clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
    743 }
    744 
    745 void strcmp_embedded_null () {
    746 	clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
    747 }
    748 
    749 void strcmp_unknown_arg (char *unknown) {
    750 	clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
    751 }
    752 
    753 //===----------------------------------------------------------------------===
    754 // strncmp()
    755 //===----------------------------------------------------------------------===
    756 
    757 #define strncmp BUILTIN(strncmp)
    758 int strncmp(const char *s1, const char *s2, size_t n);
    759 
    760 void strncmp_constant0() {
    761   clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
    762 }
    763 
    764 void strncmp_constant_and_var_0() {
    765   char *x = "123";
    766   clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
    767 }
    768 
    769 void strncmp_constant_and_var_1() {
    770   char *x = "123";
    771   clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
    772 }
    773 
    774 void strncmp_0() {
    775   char *x = "123";
    776   char *y = "123";
    777   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    778 }
    779 
    780 void strncmp_1() {
    781   char *x = "234";
    782   char *y = "123";
    783   clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
    784 }
    785 
    786 void strncmp_2() {
    787   char *x = "123";
    788   char *y = "234";
    789   clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
    790 }
    791 
    792 void strncmp_null_0() {
    793   char *x = NULL;
    794   char *y = "123";
    795   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    796 }
    797 
    798 void strncmp_null_1() {
    799   char *x = "123";
    800   char *y = NULL;
    801   strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    802 }
    803 
    804 void strncmp_diff_length_0() {
    805   char *x = "12345";
    806   char *y = "234";
    807   clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    808 }
    809 
    810 void strncmp_diff_length_1() {
    811   char *x = "123";
    812   char *y = "23456";
    813   clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    814 }
    815 
    816 void strncmp_diff_length_2() {
    817   char *x = "12345";
    818   char *y = "123";
    819   clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}}
    820 }
    821 
    822 void strncmp_diff_length_3() {
    823   char *x = "123";
    824   char *y = "12345";
    825   clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    826 }
    827 
    828 void strncmp_diff_length_4() {
    829   char *x = "123";
    830   char *y = "12345";
    831   clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    832 }
    833 
    834 void strncmp_diff_length_5() {
    835   char *x = "012";
    836   char *y = "12345";
    837   clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
    838 }
    839 
    840 void strncmp_diff_length_6() {
    841   char *x = "234";
    842   char *y = "12345";
    843   clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
    844 }
    845 
    846 void strncmp_embedded_null () {
    847 	clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
    848 }
    849 
    850 //===----------------------------------------------------------------------===
    851 // strcasecmp()
    852 //===----------------------------------------------------------------------===
    853 
    854 #define strcasecmp BUILTIN(strcasecmp)
    855 int strcasecmp(const char *s1, const char *s2);
    856 
    857 void strcasecmp_constant0() {
    858   clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
    859 }
    860 
    861 void strcasecmp_constant_and_var_0() {
    862   char *x = "abc";
    863   clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
    864 }
    865 
    866 void strcasecmp_constant_and_var_1() {
    867   char *x = "abc";
    868   clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
    869 }
    870 
    871 void strcasecmp_0() {
    872   char *x = "abc";
    873   char *y = "Abc";
    874   clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
    875 }
    876 
    877 void strcasecmp_1() {
    878   char *x = "Bcd";
    879   char *y = "abc";
    880   clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
    881 }
    882 
    883 void strcasecmp_2() {
    884   char *x = "abc";
    885   char *y = "Bcd";
    886   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    887 }
    888 
    889 void strcasecmp_null_0() {
    890   char *x = NULL;
    891   char *y = "123";
    892   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    893 }
    894 
    895 void strcasecmp_null_1() {
    896   char *x = "123";
    897   char *y = NULL;
    898   strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}}
    899 }
    900 
    901 void strcasecmp_diff_length_0() {
    902   char *x = "abcde";
    903   char *y = "aBd";
    904   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    905 }
    906 
    907 void strcasecmp_diff_length_1() {
    908   char *x = "abc";
    909   char *y = "aBdef";
    910   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    911 }
    912 
    913 void strcasecmp_diff_length_2() {
    914   char *x = "aBcDe";
    915   char *y = "abc";
    916   clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
    917 }
    918 
    919 void strcasecmp_diff_length_3() {
    920   char *x = "aBc";
    921   char *y = "abcde";
    922   clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
    923 }
    924 
    925 void strcasecmp_embedded_null () {
    926 	clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
    927 }
    928 
    929 //===----------------------------------------------------------------------===
    930 // strncasecmp()
    931 //===----------------------------------------------------------------------===
    932 
    933 #define strncasecmp BUILTIN(strncasecmp)
    934 int strncasecmp(const char *s1, const char *s2, size_t n);
    935 
    936 void strncasecmp_constant0() {
    937   clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
    938 }
    939 
    940 void strncasecmp_constant_and_var_0() {
    941   char *x = "abc";
    942   clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
    943 }
    944 
    945 void strncasecmp_constant_and_var_1() {
    946   char *x = "abc";
    947   clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
    948 }
    949 
    950 void strncasecmp_0() {
    951   char *x = "abc";
    952   char *y = "Abc";
    953   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
    954 }
    955 
    956 void strncasecmp_1() {
    957   char *x = "Bcd";
    958   char *y = "abc";
    959   clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
    960 }
    961 
    962 void strncasecmp_2() {
    963   char *x = "abc";
    964   char *y = "Bcd";
    965   clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
    966 }
    967 
    968 void strncasecmp_null_0() {
    969   char *x = NULL;
    970   char *y = "123";
    971   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    972 }
    973 
    974 void strncasecmp_null_1() {
    975   char *x = "123";
    976   char *y = NULL;
    977   strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}}
    978 }
    979 
    980 void strncasecmp_diff_length_0() {
    981   char *x = "abcde";
    982   char *y = "aBd";
    983   clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    984 }
    985 
    986 void strncasecmp_diff_length_1() {
    987   char *x = "abc";
    988   char *y = "aBdef";
    989   clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
    990 }
    991 
    992 void strncasecmp_diff_length_2() {
    993   char *x = "aBcDe";
    994   char *y = "abc";
    995   clang_analyzer_eval(strncasecmp(x, y, 5) == 1); // expected-warning{{TRUE}}
    996 }
    997 
    998 void strncasecmp_diff_length_3() {
    999   char *x = "aBc";
   1000   char *y = "abcde";
   1001   clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
   1002 }
   1003 
   1004 void strncasecmp_diff_length_4() {
   1005   char *x = "abcde";
   1006   char *y = "aBc";
   1007   clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
   1008 }
   1009 
   1010 void strncasecmp_diff_length_5() {
   1011   char *x = "abcde";
   1012   char *y = "aBd";
   1013   clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
   1014 }
   1015 
   1016 void strncasecmp_diff_length_6() {
   1017   char *x = "aBDe";
   1018   char *y = "abc";
   1019   clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
   1020 }
   1021 
   1022 void strncasecmp_embedded_null () {
   1023 	clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
   1024 }
   1025 
   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.
   1034 void 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.
   1042 void 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 }
   1052