1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 2 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 3 // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 4 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 5 // RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify -analyzer-config eagerly-assume=false %s 6 7 //===----------------------------------------------------------------------=== 8 // Declarations 9 //===----------------------------------------------------------------------=== 10 11 // Some functions are so similar to each other that they follow the same code 12 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is 13 // defined, make sure to use the variants instead to make sure they are still 14 // checked by the analyzer. 15 16 // Some functions are implemented as builtins. These should be #defined as 17 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined. 18 19 // Functions that have variants and are also available as builtins should be 20 // declared carefully! See memcpy() for an example. 21 22 #ifdef USE_BUILTINS 23 # define BUILTIN(f) __builtin_ ## f 24 #else /* USE_BUILTINS */ 25 # define BUILTIN(f) f 26 #endif /* USE_BUILTINS */ 27 28 #define NULL 0 29 typedef typeof(sizeof(int)) size_t; 30 31 void clang_analyzer_eval(int); 32 33 int scanf(const char *restrict format, ...); 34 void *malloc(size_t); 35 void free(void *); 36 37 //===----------------------------------------------------------------------=== 38 // strlen() 39 //===----------------------------------------------------------------------=== 40 41 #define strlen BUILTIN(strlen) 42 size_t strlen(const char *s); 43 44 void strlen_constant0() { 45 clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}} 46 } 47 48 void strlen_constant1() { 49 const char *a = "123"; 50 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}} 51 } 52 53 void strlen_constant2(char x) { 54 char a[] = "123"; 55 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}} 56 57 a[0] = x; 58 clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}} 59 } 60 61 size_t strlen_null() { 62 return strlen(0); // expected-warning{{Null pointer argument in call to string length function}} 63 } 64 65 size_t strlen_fn() { 66 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}} 67 } 68 69 size_t strlen_nonloc() { 70 label: 71 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}} 72 } 73 74 void strlen_subregion() { 75 struct two_strings { char a[2], b[2]; }; 76 extern void use_two_strings(struct two_strings *); 77 78 struct two_strings z; 79 use_two_strings(&z); 80 81 size_t a = strlen(z.a); 82 z.b[0] = 5; 83 size_t b = strlen(z.a); 84 if (a == 0) 85 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 86 87 use_two_strings(&z); 88 89 size_t c = strlen(z.a); 90 if (a == 0) 91 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 92 } 93 94 extern void use_string(char *); 95 void strlen_argument(char *x) { 96 size_t a = strlen(x); 97 size_t b = strlen(x); 98 if (a == 0) 99 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 100 101 use_string(x); 102 103 size_t c = strlen(x); 104 if (a == 0) 105 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 106 } 107 108 extern char global_str[]; 109 void strlen_global() { 110 size_t a = strlen(global_str); 111 size_t b = strlen(global_str); 112 if (a == 0) { 113 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 114 // Make sure clang_analyzer_eval does not invalidate globals. 115 clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}} 116 } 117 118 // Call a function with unknown effects, which should invalidate globals. 119 use_string(0); 120 121 size_t c = strlen(global_str); 122 if (a == 0) 123 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 124 } 125 126 void strlen_indirect(char *x) { 127 size_t a = strlen(x); 128 char *p = x; 129 char **p2 = &p; 130 size_t b = strlen(x); 131 if (a == 0) 132 clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} 133 134 extern void use_string_ptr(char*const*); 135 use_string_ptr(p2); 136 137 size_t c = strlen(x); 138 if (a == 0) 139 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 140 } 141 142 void strlen_indirect2(char *x) { 143 size_t a = strlen(x); 144 char *p = x; 145 char **p2 = &p; 146 extern void use_string_ptr2(char**); 147 use_string_ptr2(p2); 148 149 size_t c = strlen(x); 150 if (a == 0) 151 clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}} 152 } 153 154 void strlen_liveness(const char *x) { 155 if (strlen(x) < 5) 156 return; 157 clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}} 158 } 159 160 161 size_t strlenWrapper(const char *str) { 162 return strlen(str); 163 } 164 165 extern void invalidate(char *s); 166 167 void testStrlenCallee() { 168 char str[42]; 169 invalidate(str); 170 size_t lenBefore = strlenWrapper(str); 171 invalidate(str); 172 size_t lenAfter = strlenWrapper(str); 173 clang_analyzer_eval(lenBefore == lenAfter); // expected-warning{{UNKNOWN}} 174 } 175 176 177 //===----------------------------------------------------------------------=== 178 // strnlen() 179 //===----------------------------------------------------------------------=== 180 181 size_t strnlen(const char *s, size_t maxlen); 182 183 void strnlen_constant0() { 184 clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}} 185 } 186 187 void strnlen_constant1() { 188 const char *a = "123"; 189 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}} 190 } 191 192 void strnlen_constant2(char x) { 193 char a[] = "123"; 194 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}} 195 a[0] = x; 196 clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}} 197 } 198 199 void strnlen_constant4() { 200 clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}} 201 } 202 203 void strnlen_constant5() { 204 const char *a = "123456"; 205 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}} 206 } 207 208 void strnlen_constant6(char x) { 209 char a[] = "123456"; 210 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}} 211 a[0] = x; 212 clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}} 213 } 214 215 size_t strnlen_null() { 216 return strnlen(0, 3); // expected-warning{{Null pointer argument in call to string length function}} 217 } 218 219 size_t strnlen_fn() { 220 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}} 221 } 222 223 size_t strnlen_nonloc() { 224 label: 225 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}} 226 } 227 228 void strnlen_zero() { 229 clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}} 230 clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}} 231 } 232 233 size_t strnlen_compound_literal() { 234 // This used to crash because we don't model the string lengths of 235 // compound literals. 236 return strnlen((char[]) { 'a', 'b', 0 }, 1); 237 } 238 239 size_t strnlen_unknown_limit(float f) { 240 // This used to crash because we don't model the integer values of floats. 241 return strnlen("abc", (int)f); 242 } 243 244 void strnlen_is_not_strlen(char *x) { 245 clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}} 246 } 247 248 void strnlen_at_limit(char *x) { 249 size_t len = strnlen(x, 10); 250 clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}} 251 clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}} 252 clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}} 253 } 254 255 void strnlen_at_actual(size_t limit) { 256 size_t len = strnlen("abc", limit); 257 clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}} 258 // This is due to eager assertion in strnlen. 259 if (limit == 0) { 260 clang_analyzer_eval(len == 0); // expected-warning{{TRUE}} 261 } else { 262 clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}} 263 clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}} 264 } 265 } 266 267 //===----------------------------------------------------------------------=== 268 // strcpy() 269 //===----------------------------------------------------------------------=== 270 271 #ifdef VARIANT 272 273 #define __strcpy_chk BUILTIN(__strcpy_chk) 274 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 275 276 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1) 277 278 #else /* VARIANT */ 279 280 #define strcpy BUILTIN(strcpy) 281 char *strcpy(char *restrict s1, const char *restrict s2); 282 283 #endif /* VARIANT */ 284 285 286 void strcpy_null_dst(char *x) { 287 strcpy(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} 288 } 289 290 void strcpy_null_src(char *x) { 291 strcpy(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} 292 } 293 294 void strcpy_fn(char *x) { 295 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}} 296 } 297 298 void strcpy_fn_const(char *x) { 299 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}} 300 } 301 302 extern int globalInt; 303 void strcpy_effects(char *x, char *y) { 304 char a = x[0]; 305 if (globalInt != 42) 306 return; 307 308 clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}} 309 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} 310 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 311 clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}} 312 } 313 314 #ifndef SUPPRESS_OUT_OF_BOUND 315 void strcpy_overflow(char *y) { 316 char x[4]; 317 if (strlen(y) == 4) 318 strcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} 319 } 320 #endif 321 322 void strcpy_no_overflow(char *y) { 323 char x[4]; 324 if (strlen(y) == 3) 325 strcpy(x, y); // no-warning 326 } 327 328 //===----------------------------------------------------------------------=== 329 // stpcpy() 330 //===----------------------------------------------------------------------=== 331 332 #ifdef VARIANT 333 334 #define __stpcpy_chk BUILTIN(__stpcpy_chk) 335 char *__stpcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 336 337 #define stpcpy(a,b) __stpcpy_chk(a,b,(size_t)-1) 338 339 #else /* VARIANT */ 340 341 #define stpcpy BUILTIN(stpcpy) 342 char *stpcpy(char *restrict s1, const char *restrict s2); 343 344 #endif /* VARIANT */ 345 346 347 void stpcpy_effect(char *x, char *y) { 348 char a = x[0]; 349 350 clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}} 351 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}} 352 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 353 } 354 355 #ifndef SUPPRESS_OUT_OF_BOUND 356 void stpcpy_overflow(char *y) { 357 char x[4]; 358 if (strlen(y) == 4) 359 stpcpy(x, y); // expected-warning{{String copy function overflows destination buffer}} 360 } 361 #endif 362 363 void stpcpy_no_overflow(char *y) { 364 char x[4]; 365 if (strlen(y) == 3) 366 stpcpy(x, y); // no-warning 367 } 368 369 //===----------------------------------------------------------------------=== 370 // strcat() 371 //===----------------------------------------------------------------------=== 372 373 #ifdef VARIANT 374 375 #define __strcat_chk BUILTIN(__strcat_chk) 376 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen); 377 378 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1) 379 380 #else /* VARIANT */ 381 382 #define strcat BUILTIN(strcat) 383 char *strcat(char *restrict s1, const char *restrict s2); 384 385 #endif /* VARIANT */ 386 387 388 void strcat_null_dst(char *x) { 389 strcat(NULL, x); // expected-warning{{Null pointer argument in call to string copy function}} 390 } 391 392 void strcat_null_src(char *x) { 393 strcat(x, NULL); // expected-warning{{Null pointer argument in call to string copy function}} 394 } 395 396 void strcat_fn(char *x) { 397 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}} 398 } 399 400 void strcat_effects(char *y) { 401 char x[8] = "123"; 402 size_t orig_len = strlen(x); 403 char a = x[0]; 404 405 if (strlen(y) != 4) 406 return; 407 408 clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}} 409 clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 410 } 411 412 #ifndef SUPPRESS_OUT_OF_BOUND 413 void strcat_overflow_0(char *y) { 414 char x[4] = "12"; 415 if (strlen(y) == 4) 416 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 417 } 418 419 void strcat_overflow_1(char *y) { 420 char x[4] = "12"; 421 if (strlen(y) == 3) 422 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 423 } 424 425 void strcat_overflow_2(char *y) { 426 char x[4] = "12"; 427 if (strlen(y) == 2) 428 strcat(x, y); // expected-warning{{String copy function overflows destination buffer}} 429 } 430 #endif 431 432 void strcat_no_overflow(char *y) { 433 char x[5] = "12"; 434 if (strlen(y) == 2) 435 strcat(x, y); // no-warning 436 } 437 438 void strcat_symbolic_dst_length(char *dst) { 439 strcat(dst, "1234"); 440 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 441 } 442 443 void strcat_symbolic_dst_length_taint(char *dst) { 444 scanf("%s", dst); // Taint data. 445 strcat(dst, "1234"); 446 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 447 } 448 449 void strcat_unknown_src_length(char *src, int offset) { 450 char dst[8] = "1234"; 451 strcat(dst, &src[offset]); 452 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 453 } 454 455 // There is no strcat_unknown_dst_length because if we can't get a symbolic 456 // length for the "before" strlen, we won't be able to set one for "after". 457 458 void strcat_too_big(char *dst, char *src) { 459 // We assume this can never actually happen, so we don't get a warning. 460 if (strlen(dst) != (((size_t)0) - 2)) 461 return; 462 if (strlen(src) != 2) 463 return; 464 strcat(dst, src); 465 } 466 467 468 //===----------------------------------------------------------------------=== 469 // strncpy() 470 //===----------------------------------------------------------------------=== 471 472 #ifdef VARIANT 473 474 #define __strncpy_chk BUILTIN(__strncpy_chk) 475 char *__strncpy_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 476 477 #define strncpy(a,b,n) __strncpy_chk(a,b,n,(size_t)-1) 478 479 #else /* VARIANT */ 480 481 #define strncpy BUILTIN(strncpy) 482 char *strncpy(char *restrict s1, const char *restrict s2, size_t n); 483 484 #endif /* VARIANT */ 485 486 487 void strncpy_null_dst(char *x) { 488 strncpy(NULL, x, 5); // expected-warning{{Null pointer argument in call to string copy function}} 489 } 490 491 void strncpy_null_src(char *x) { 492 strncpy(x, NULL, 5); // expected-warning{{Null pointer argument in call to string copy function}} 493 } 494 495 void strncpy_fn(char *x) { 496 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}} 497 } 498 499 void strncpy_effects(char *x, char *y) { 500 char a = x[0]; 501 502 clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}} 503 clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}} 504 clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}} 505 } 506 507 #ifndef SUPPRESS_OUT_OF_BOUND 508 // Enabling the malloc checker enables some of the buffer-checking portions 509 // of the C-string checker. 510 void cstringchecker_bounds_nocrash() { 511 char *p = malloc(2); 512 strncpy(p, "AAA", sizeof("AAA")); // expected-warning {{Size argument is greater than the length of the destination buffer}} 513 free(p); 514 } 515 516 void strncpy_overflow(char *y) { 517 char x[4]; 518 if (strlen(y) == 4) 519 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 520 } 521 522 void strncpy_no_overflow(char *y) { 523 char x[4]; 524 if (strlen(y) == 3) 525 strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} 526 } 527 528 void strncpy_no_overflow2(char *y, int n) { 529 if (n <= 4) 530 return; 531 532 char x[4]; 533 if (strlen(y) == 3) 534 strncpy(x, y, n); // expected-warning{{Size argument is greater than the length of the destination buffer}} 535 } 536 #endif 537 538 void strncpy_truncate(char *y) { 539 char x[4]; 540 if (strlen(y) == 4) 541 strncpy(x, y, 3); // no-warning 542 } 543 544 void strncpy_no_truncate(char *y) { 545 char x[4]; 546 if (strlen(y) == 3) 547 strncpy(x, y, 3); // no-warning 548 } 549 550 void strncpy_exactly_matching_buffer(char *y) { 551 char x[4]; 552 strncpy(x, y, 4); // no-warning 553 554 // strncpy does not null-terminate, so we have no idea what the strlen is 555 // after this. 556 clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} 557 } 558 559 void strncpy_zero(char *src) { 560 char dst[] = "123"; 561 strncpy(dst, src, 0); // no-warning 562 } 563 564 void strncpy_empty() { 565 char dst[] = "123"; 566 char src[] = ""; 567 strncpy(dst, src, 4); // no-warning 568 } 569 570 //===----------------------------------------------------------------------=== 571 // strncat() 572 //===----------------------------------------------------------------------=== 573 574 #ifdef VARIANT 575 576 #define __strncat_chk BUILTIN(__strncat_chk) 577 char *__strncat_chk(char *restrict s1, const char *restrict s2, size_t n, size_t destlen); 578 579 #define strncat(a,b,c) __strncat_chk(a,b,c, (size_t)-1) 580 581 #else /* VARIANT */ 582 583 #define strncat BUILTIN(strncat) 584 char *strncat(char *restrict s1, const char *restrict s2, size_t n); 585 586 #endif /* VARIANT */ 587 588 589 void strncat_null_dst(char *x) { 590 strncat(NULL, x, 4); // expected-warning{{Null pointer argument in call to string copy function}} 591 } 592 593 void strncat_null_src(char *x) { 594 strncat(x, NULL, 4); // expected-warning{{Null pointer argument in call to string copy function}} 595 } 596 597 void strncat_fn(char *x) { 598 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}} 599 } 600 601 void strncat_effects(char *y) { 602 char x[8] = "123"; 603 size_t orig_len = strlen(x); 604 char a = x[0]; 605 606 if (strlen(y) != 4) 607 return; 608 609 clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}} 610 clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}} 611 } 612 613 #ifndef SUPPRESS_OUT_OF_BOUND 614 void strncat_overflow_0(char *y) { 615 char x[4] = "12"; 616 if (strlen(y) == 4) 617 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 618 } 619 620 void strncat_overflow_1(char *y) { 621 char x[4] = "12"; 622 if (strlen(y) == 3) 623 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 624 } 625 626 void strncat_overflow_2(char *y) { 627 char x[4] = "12"; 628 if (strlen(y) == 2) 629 strncat(x, y, strlen(y)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 630 } 631 632 void strncat_overflow_3(char *y) { 633 char x[4] = "12"; 634 if (strlen(y) == 4) 635 strncat(x, y, 2); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 636 } 637 #endif 638 639 void strncat_no_overflow_1(char *y) { 640 char x[5] = "12"; 641 if (strlen(y) == 2) 642 strncat(x, y, strlen(y)); // no-warning 643 } 644 645 void strncat_no_overflow_2(char *y) { 646 char x[4] = "12"; 647 if (strlen(y) == 4) 648 strncat(x, y, 1); // no-warning 649 } 650 651 void strncat_symbolic_dst_length(char *dst) { 652 strncat(dst, "1234", 5); 653 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 654 } 655 656 #ifndef SUPPRESS_OUT_OF_BOUND 657 void strncat_symbolic_src_length(char *src) { 658 char dst[8] = "1234"; 659 strncat(dst, src, 3); 660 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 661 662 char dst2[8] = "1234"; 663 strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 664 } 665 666 void strncat_unknown_src_length(char *src, int offset) { 667 char dst[8] = "1234"; 668 strncat(dst, &src[offset], 3); 669 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 670 671 char dst2[8] = "1234"; 672 strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}} 673 } 674 #endif 675 676 // There is no strncat_unknown_dst_length because if we can't get a symbolic 677 // length for the "before" strlen, we won't be able to set one for "after". 678 679 void strncat_symbolic_limit(unsigned limit) { 680 char dst[6] = "1234"; 681 char src[] = "567"; 682 strncat(dst, src, limit); // no-warning 683 684 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 685 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 686 } 687 688 void strncat_unknown_limit(float limit) { 689 char dst[6] = "1234"; 690 char src[] = "567"; 691 strncat(dst, src, (size_t)limit); // no-warning 692 693 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} 694 clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}} 695 } 696 697 void strncat_too_big(char *dst, char *src) { 698 // We assume this will never actually happen, so we don't get a warning. 699 if (strlen(dst) != (((size_t)0) - 2)) 700 return; 701 if (strlen(src) != 2) 702 return; 703 strncat(dst, src, 2); 704 } 705 706 void strncat_zero(char *src) { 707 char dst[] = "123"; 708 strncat(dst, src, 0); // no-warning 709 } 710 711 void strncat_empty() { 712 char dst[8] = "123"; 713 char src[] = ""; 714 strncat(dst, src, 4); // no-warning 715 } 716 717 //===----------------------------------------------------------------------=== 718 // strcmp() 719 //===----------------------------------------------------------------------=== 720 721 #define strcmp BUILTIN(strcmp) 722 int strcmp(const char * s1, const char * s2); 723 724 void strcmp_check_modelling() { 725 char *x = "aa"; 726 char *y = "a"; 727 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 728 clang_analyzer_eval(strcmp(x, y) <= 0); // expected-warning{{FALSE}} 729 clang_analyzer_eval(strcmp(x, y) > 1); // expected-warning{{UNKNOWN}} 730 731 clang_analyzer_eval(strcmp(y, x) < 0); // expected-warning{{TRUE}} 732 clang_analyzer_eval(strcmp(y, x) >= 0); // expected-warning{{FALSE}} 733 clang_analyzer_eval(strcmp(y, x) < -1); // expected-warning{{UNKNOWN}} 734 } 735 736 void strcmp_constant0() { 737 clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}} 738 } 739 740 void strcmp_constant_and_var_0() { 741 char *x = "123"; 742 clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}} 743 } 744 745 void strcmp_constant_and_var_1() { 746 char *x = "123"; 747 clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}} 748 } 749 750 void strcmp_0() { 751 char *x = "123"; 752 char *y = "123"; 753 clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}} 754 } 755 756 void strcmp_1() { 757 char *x = "234"; 758 char *y = "123"; 759 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 760 } 761 762 void strcmp_2() { 763 char *x = "123"; 764 char *y = "234"; 765 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 766 } 767 768 void strcmp_null_0() { 769 char *x = NULL; 770 char *y = "123"; 771 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 772 } 773 774 void strcmp_null_1() { 775 char *x = "123"; 776 char *y = NULL; 777 strcmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 778 } 779 780 void strcmp_diff_length_0() { 781 char *x = "12345"; 782 char *y = "234"; 783 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 784 } 785 786 void strcmp_diff_length_1() { 787 char *x = "123"; 788 char *y = "23456"; 789 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 790 } 791 792 void strcmp_diff_length_2() { 793 char *x = "12345"; 794 char *y = "123"; 795 clang_analyzer_eval(strcmp(x, y) > 0); // expected-warning{{TRUE}} 796 } 797 798 void strcmp_diff_length_3() { 799 char *x = "123"; 800 char *y = "12345"; 801 clang_analyzer_eval(strcmp(x, y) < 0); // expected-warning{{TRUE}} 802 } 803 804 void strcmp_embedded_null () { 805 clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}} 806 } 807 808 void strcmp_unknown_arg (char *unknown) { 809 clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}} 810 } 811 812 union argument { 813 char *f; 814 }; 815 816 void function_pointer_cast_helper(char **a) { 817 strcmp("Hi", *a); // PR24951 crash 818 } 819 820 void strcmp_union_function_pointer_cast(union argument a) { 821 void (*fPtr)(union argument *) = (void (*)(union argument *))function_pointer_cast_helper; 822 823 fPtr(&a); 824 } 825 826 //===----------------------------------------------------------------------=== 827 // strncmp() 828 //===----------------------------------------------------------------------=== 829 830 #define strncmp BUILTIN(strncmp) 831 int strncmp(const char *s1, const char *s2, size_t n); 832 833 void strncmp_check_modelling() { 834 char *x = "aa"; 835 char *y = "a"; 836 clang_analyzer_eval(strncmp(x, y, 2) > 0); // expected-warning{{TRUE}} 837 clang_analyzer_eval(strncmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 838 clang_analyzer_eval(strncmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 839 840 clang_analyzer_eval(strncmp(y, x, 2) < 0); // expected-warning{{TRUE}} 841 clang_analyzer_eval(strncmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 842 clang_analyzer_eval(strncmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 843 } 844 845 void strncmp_constant0() { 846 clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}} 847 } 848 849 void strncmp_constant_and_var_0() { 850 char *x = "123"; 851 clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}} 852 } 853 854 void strncmp_constant_and_var_1() { 855 char *x = "123"; 856 clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}} 857 } 858 859 void strncmp_0() { 860 char *x = "123"; 861 char *y = "123"; 862 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 863 } 864 865 void strncmp_1() { 866 char *x = "234"; 867 char *y = "123"; 868 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 869 } 870 871 void strncmp_2() { 872 char *x = "123"; 873 char *y = "234"; 874 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 875 } 876 877 void strncmp_null_0() { 878 char *x = NULL; 879 char *y = "123"; 880 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 881 } 882 883 void strncmp_null_1() { 884 char *x = "123"; 885 char *y = NULL; 886 strncmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 887 } 888 889 void strncmp_diff_length_0() { 890 char *x = "12345"; 891 char *y = "234"; 892 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 893 } 894 895 void strncmp_diff_length_1() { 896 char *x = "123"; 897 char *y = "23456"; 898 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 899 } 900 901 void strncmp_diff_length_2() { 902 char *x = "12345"; 903 char *y = "123"; 904 clang_analyzer_eval(strncmp(x, y, 5) > 0); // expected-warning{{TRUE}} 905 } 906 907 void strncmp_diff_length_3() { 908 char *x = "123"; 909 char *y = "12345"; 910 clang_analyzer_eval(strncmp(x, y, 5) < 0); // expected-warning{{TRUE}} 911 } 912 913 void strncmp_diff_length_4() { 914 char *x = "123"; 915 char *y = "12345"; 916 clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}} 917 } 918 919 void strncmp_diff_length_5() { 920 char *x = "012"; 921 char *y = "12345"; 922 clang_analyzer_eval(strncmp(x, y, 3) < 0); // expected-warning{{TRUE}} 923 } 924 925 void strncmp_diff_length_6() { 926 char *x = "234"; 927 char *y = "12345"; 928 clang_analyzer_eval(strncmp(x, y, 3) > 0); // expected-warning{{TRUE}} 929 } 930 931 void strncmp_embedded_null () { 932 clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 933 } 934 935 //===----------------------------------------------------------------------=== 936 // strcasecmp() 937 //===----------------------------------------------------------------------=== 938 939 #define strcasecmp BUILTIN(strcasecmp) 940 int strcasecmp(const char *s1, const char *s2); 941 942 void strcasecmp_check_modelling() { 943 char *x = "aa"; 944 char *y = "a"; 945 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 946 clang_analyzer_eval(strcasecmp(x, y) <= 0); // expected-warning{{FALSE}} 947 clang_analyzer_eval(strcasecmp(x, y) > 1); // expected-warning{{UNKNOWN}} 948 949 clang_analyzer_eval(strcasecmp(y, x) < 0); // expected-warning{{TRUE}} 950 clang_analyzer_eval(strcasecmp(y, x) >= 0); // expected-warning{{FALSE}} 951 clang_analyzer_eval(strcasecmp(y, x) < -1); // expected-warning{{UNKNOWN}} 952 } 953 954 void strcasecmp_constant0() { 955 clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}} 956 } 957 958 void strcasecmp_constant_and_var_0() { 959 char *x = "abc"; 960 clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}} 961 } 962 963 void strcasecmp_constant_and_var_1() { 964 char *x = "abc"; 965 clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}} 966 } 967 968 void strcasecmp_0() { 969 char *x = "abc"; 970 char *y = "Abc"; 971 clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}} 972 } 973 974 void strcasecmp_1() { 975 char *x = "Bcd"; 976 char *y = "abc"; 977 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 978 } 979 980 void strcasecmp_2() { 981 char *x = "abc"; 982 char *y = "Bcd"; 983 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 984 } 985 986 void strcasecmp_null_0() { 987 char *x = NULL; 988 char *y = "123"; 989 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 990 } 991 992 void strcasecmp_null_1() { 993 char *x = "123"; 994 char *y = NULL; 995 strcasecmp(x, y); // expected-warning{{Null pointer argument in call to string comparison function}} 996 } 997 998 void strcasecmp_diff_length_0() { 999 char *x = "abcde"; 1000 char *y = "aBd"; 1001 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1002 } 1003 1004 void strcasecmp_diff_length_1() { 1005 char *x = "abc"; 1006 char *y = "aBdef"; 1007 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1008 } 1009 1010 void strcasecmp_diff_length_2() { 1011 char *x = "aBcDe"; 1012 char *y = "abc"; 1013 clang_analyzer_eval(strcasecmp(x, y) > 0); // expected-warning{{TRUE}} 1014 } 1015 1016 void strcasecmp_diff_length_3() { 1017 char *x = "aBc"; 1018 char *y = "abcde"; 1019 clang_analyzer_eval(strcasecmp(x, y) < 0); // expected-warning{{TRUE}} 1020 } 1021 1022 void strcasecmp_embedded_null () { 1023 clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}} 1024 } 1025 1026 //===----------------------------------------------------------------------=== 1027 // strncasecmp() 1028 //===----------------------------------------------------------------------=== 1029 1030 #define strncasecmp BUILTIN(strncasecmp) 1031 int strncasecmp(const char *s1, const char *s2, size_t n); 1032 1033 void strncasecmp_check_modelling() { 1034 char *x = "aa"; 1035 char *y = "a"; 1036 clang_analyzer_eval(strncasecmp(x, y, 2) > 0); // expected-warning{{TRUE}} 1037 clang_analyzer_eval(strncasecmp(x, y, 2) <= 0); // expected-warning{{FALSE}} 1038 clang_analyzer_eval(strncasecmp(x, y, 2) > 1); // expected-warning{{UNKNOWN}} 1039 1040 clang_analyzer_eval(strncasecmp(y, x, 2) < 0); // expected-warning{{TRUE}} 1041 clang_analyzer_eval(strncasecmp(y, x, 2) >= 0); // expected-warning{{FALSE}} 1042 clang_analyzer_eval(strncasecmp(y, x, 2) < -1); // expected-warning{{UNKNOWN}} 1043 } 1044 1045 void strncasecmp_constant0() { 1046 clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}} 1047 } 1048 1049 void strncasecmp_constant_and_var_0() { 1050 char *x = "abc"; 1051 clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}} 1052 } 1053 1054 void strncasecmp_constant_and_var_1() { 1055 char *x = "abc"; 1056 clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}} 1057 } 1058 1059 void strncasecmp_0() { 1060 char *x = "abc"; 1061 char *y = "Abc"; 1062 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1063 } 1064 1065 void strncasecmp_1() { 1066 char *x = "Bcd"; 1067 char *y = "abc"; 1068 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1069 } 1070 1071 void strncasecmp_2() { 1072 char *x = "abc"; 1073 char *y = "Bcd"; 1074 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1075 } 1076 1077 void strncasecmp_null_0() { 1078 char *x = NULL; 1079 char *y = "123"; 1080 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 1081 } 1082 1083 void strncasecmp_null_1() { 1084 char *x = "123"; 1085 char *y = NULL; 1086 strncasecmp(x, y, 3); // expected-warning{{Null pointer argument in call to string comparison function}} 1087 } 1088 1089 void strncasecmp_diff_length_0() { 1090 char *x = "abcde"; 1091 char *y = "aBd"; 1092 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1093 } 1094 1095 void strncasecmp_diff_length_1() { 1096 char *x = "abc"; 1097 char *y = "aBdef"; 1098 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1099 } 1100 1101 void strncasecmp_diff_length_2() { 1102 char *x = "aBcDe"; 1103 char *y = "abc"; 1104 clang_analyzer_eval(strncasecmp(x, y, 5) > 0); // expected-warning{{TRUE}} 1105 } 1106 1107 void strncasecmp_diff_length_3() { 1108 char *x = "aBc"; 1109 char *y = "abcde"; 1110 clang_analyzer_eval(strncasecmp(x, y, 5) < 0); // expected-warning{{TRUE}} 1111 } 1112 1113 void strncasecmp_diff_length_4() { 1114 char *x = "abcde"; 1115 char *y = "aBc"; 1116 clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}} 1117 } 1118 1119 void strncasecmp_diff_length_5() { 1120 char *x = "abcde"; 1121 char *y = "aBd"; 1122 clang_analyzer_eval(strncasecmp(x, y, 3) < 0); // expected-warning{{TRUE}} 1123 } 1124 1125 void strncasecmp_diff_length_6() { 1126 char *x = "aBDe"; 1127 char *y = "abc"; 1128 clang_analyzer_eval(strncasecmp(x, y, 3) > 0); // expected-warning{{TRUE}} 1129 } 1130 1131 void strncasecmp_embedded_null () { 1132 clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}} 1133 } 1134 1135 //===----------------------------------------------------------------------=== 1136 // strsep() 1137 //===----------------------------------------------------------------------=== 1138 1139 char *strsep(char **stringp, const char *delim); 1140 1141 void strsep_null_delim(char *s) { 1142 strsep(&s, NULL); // expected-warning{{Null pointer argument in call to strsep()}} 1143 } 1144 1145 void strsep_null_search() { 1146 strsep(NULL, ""); // expected-warning{{Null pointer argument in call to strsep()}} 1147 } 1148 1149 void strsep_return_original_pointer(char *s) { 1150 char *original = s; 1151 char *result = strsep(&s, ""); // no-warning 1152 clang_analyzer_eval(original == result); // expected-warning{{TRUE}} 1153 } 1154 1155 void strsep_null_string() { 1156 char *s = NULL; 1157 char *result = strsep(&s, ""); // no-warning 1158 clang_analyzer_eval(result == NULL); // expected-warning{{TRUE}} 1159 } 1160 1161 void strsep_changes_input_pointer(char *s) { 1162 char *original = s; 1163 strsep(&s, ""); // no-warning 1164 clang_analyzer_eval(s == original); // expected-warning{{UNKNOWN}} 1165 clang_analyzer_eval(s == NULL); // expected-warning{{UNKNOWN}} 1166 1167 // Check that the value is symbolic. 1168 if (s == NULL) { 1169 clang_analyzer_eval(s == NULL); // expected-warning{{TRUE}} 1170 } 1171 } 1172 1173 void strsep_changes_input_string() { 1174 char str[] = "abc"; 1175 1176 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{TRUE}} 1177 1178 char *s = str; 1179 strsep(&s, "b"); // no-warning 1180 1181 // The real strsep will change the first delimiter it finds into a NUL 1182 // character. For now, we just model the invalidation. 1183 clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} 1184 } 1185 1186 //===----------------------------------------------------------------------=== 1187 // memset() 1188 //===----------------------------------------------------------------------=== 1189 1190 void *memset(void *dest, int ch, size_t count); 1191 1192 void *malloc(size_t size); 1193 void free(void *); 1194 1195 void memset1_char_array_null() { 1196 char str[] = "abcd"; 1197 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1198 memset(str, '\0', 2); 1199 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1200 } 1201 1202 void memset2_char_array_null() { 1203 char str[] = "abcd"; 1204 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1205 memset(str, '\0', strlen(str) + 1); 1206 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1207 clang_analyzer_eval(str[2] == 0); // expected-warning{{TRUE}} 1208 } 1209 1210 void memset3_char_malloc_null() { 1211 char *str = (char *)malloc(10 * sizeof(char)); 1212 memset(str + 1, '\0', 8); 1213 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1214 free(str); 1215 } 1216 1217 void memset4_char_malloc_null() { 1218 char *str = (char *)malloc(10 * sizeof(char)); 1219 //void *str = malloc(10 * sizeof(char)); 1220 memset(str, '\0', 10); 1221 clang_analyzer_eval(str[1] == 0); // expected-warning{{TRUE}} 1222 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1223 free(str); 1224 } 1225 1226 #ifdef SUPPRESS_OUT_OF_BOUND 1227 void memset5_char_malloc_overflow_null() { 1228 char *str = (char *)malloc(10 * sizeof(char)); 1229 memset(str, '\0', 12); 1230 clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}} 1231 free(str); 1232 } 1233 #endif 1234 1235 void memset6_char_array_nonnull() { 1236 char str[] = "abcd"; 1237 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1238 memset(str, '0', 2); 1239 clang_analyzer_eval(str[0] == 'a'); // expected-warning{{UNKNOWN}} 1240 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}} 1241 } 1242 1243 #ifdef SUPPRESS_OUT_OF_BOUND 1244 void memset8_char_array_nonnull() { 1245 char str[5] = "abcd"; 1246 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1247 memset(str, '0', 10); 1248 clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}} 1249 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1250 clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}} 1251 } 1252 #endif 1253 1254 struct POD_memset { 1255 int num; 1256 char c; 1257 }; 1258 1259 void memset10_struct() { 1260 struct POD_memset pod; 1261 char *str = (char *)&pod; 1262 pod.num = 1; 1263 pod.c = 1; 1264 clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}} 1265 memset(str, 0, sizeof(struct POD_memset)); 1266 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1267 } 1268 1269 #ifdef SUPPRESS_OUT_OF_BOUND 1270 void memset11_struct_field() { 1271 struct POD_memset pod; 1272 pod.num = 1; 1273 pod.c = '1'; 1274 memset(&pod.num, 0, sizeof(struct POD_memset)); 1275 1276 clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}} 1277 clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}} 1278 } 1279 1280 void memset12_struct_field() { 1281 struct POD_memset pod; 1282 pod.num = 1; 1283 pod.c = '1'; 1284 memset(&pod.c, 0, sizeof(struct POD_memset)); 1285 clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}} 1286 clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}} 1287 } 1288 1289 union U_memset { 1290 int i; 1291 double d; 1292 char c; 1293 }; 1294 1295 void memset13_union_field() { 1296 union U_memset u; 1297 u.i = 5; 1298 memset(&u.i, '\0', sizeof(union U_memset)); 1299 // Note: This should be TRUE, analyzer can't handle union perfectly now. 1300 clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}} 1301 } 1302 #endif 1303 1304 void memset14_region_cast() { 1305 char *str = (char *)malloc(10 * sizeof(int)); 1306 int *array = (int *)str; 1307 memset(array, 0, 10 * sizeof(int)); 1308 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{TRUE}} 1309 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1310 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1311 free(str); 1312 } 1313 1314 void memset15_region_cast() { 1315 char *str = (char *)malloc(10 * sizeof(int)); 1316 int *array = (int *)str; 1317 memset(array, 0, 5 * sizeof(int)); 1318 clang_analyzer_eval(str[10] == '\0'); // expected-warning{{UNKNOWN}} 1319 clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}} 1320 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} 1321 free(str); 1322 } 1323 1324 int memset20_scalar() { 1325 int *x = malloc(sizeof(int)); 1326 *x = 10; 1327 memset(x, 0, sizeof(int)); 1328 int num = 1 / *x; // expected-warning{{Division by zero}} 1329 free(x); 1330 return num; 1331 } 1332 1333 int memset21_scalar() { 1334 int *x = malloc(sizeof(int)); 1335 memset(x, 0, 1); 1336 int num = 1 / *x; 1337 free(x); 1338 return num; 1339 } 1340 1341 void memset22_array() { 1342 int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 1343 clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}} 1344 memset(array, 0, sizeof(array)); 1345 clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}} 1346 } 1347 1348 void memset23_array_pod_object() { 1349 struct POD_memset array[10]; 1350 array[1].num = 10; 1351 array[1].c = 'c'; 1352 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1353 memset(&array[1], 0, sizeof(struct POD_memset)); 1354 clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}} 1355 } 1356 1357 void memset24_array_pod_object() { 1358 struct POD_memset array[10]; 1359 array[1].num = 10; 1360 array[1].c = 'c'; 1361 clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}} 1362 memset(array, 0, sizeof(array)); 1363 clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}} 1364 } 1365 1366 void memset25_symbol(char c) { 1367 char array[10] = {1}; 1368 if (c != 0) 1369 return; 1370 1371 memset(array, c, 10); 1372 1373 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1374 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1375 } 1376 1377 void memset26_upper_UCHAR_MAX() { 1378 char array[10] = {1}; 1379 1380 memset(array, 1024, 10); 1381 1382 clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}} 1383 clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} 1384 } 1385 1386 //===----------------------------------------------------------------------=== 1387 // FIXMEs 1388 //===----------------------------------------------------------------------=== 1389 1390 // The analyzer_eval call below should evaluate to true. We are being too 1391 // aggressive in marking the (length of) src symbol dead. The length of dst 1392 // depends on src. This could be explicitly specified in the checker or the 1393 // logic for handling MetadataSymbol in SymbolManager needs to change. 1394 void strcat_symbolic_src_length(char *src) { 1395 char dst[8] = "1234"; 1396 strcat(dst, src); 1397 clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} 1398 } 1399 1400 1401 // The analyzer_eval call below should evaluate to true. Most likely the same 1402 // issue as the test above. 1403 void strncpy_exactly_matching_buffer2(char *y) { 1404 if (strlen(y) >= 4) 1405 return; 1406 1407 char x[4]; 1408 strncpy(x, y, 4); // no-warning 1409 1410 // This time, we know that y fits in x anyway. 1411 clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} 1412 } 1413 1414 void memset7_char_array_nonnull() { 1415 char str[5] = "abcd"; 1416 clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} 1417 memset(str, '0', 5); 1418 // FIXME: This should be TRUE. 1419 clang_analyzer_eval(str[0] == '0'); // expected-warning{{UNKNOWN}} 1420 clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}} 1421 } 1422 1423 void memset16_region_cast() { 1424 char *str = (char *)malloc(10 * sizeof(int)); 1425 int *array = (int *)str; 1426 memset(array, '0', 10 * sizeof(int)); 1427 // FIXME: This should be TRUE. 1428 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1429 clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1430 clang_analyzer_eval(strlen(str) >= 10 * sizeof(int)); // expected-warning{{TRUE}} 1431 free(str); 1432 } 1433 1434 #ifdef SUPPRESS_OUT_OF_BOUND 1435 void memset17_region_cast() { 1436 char *str = (char *)malloc(10 * sizeof(int)); 1437 int *array = (int *)str; 1438 memset(array, '0', 12 * sizeof(int)); 1439 clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}} 1440 clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1441 clang_analyzer_eval(strlen(str) >= 12 * sizeof(int)); // expected-warning{{TRUE}} 1442 free(str); 1443 } 1444 1445 void memset18_memset_multiple_times() { 1446 char *str = (char *)malloc(10 * sizeof(char)); 1447 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1448 1449 memset(str + 2, '\0', 10 * sizeof(char)); 1450 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1451 clang_analyzer_eval(str[1] == '\0'); // expected-warning{{UNKNOWN}} 1452 1453 memset(str, '0', 10 * sizeof(char)); 1454 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1455 // FIXME: This should be TRUE. 1456 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1457 1458 free(str); 1459 } 1460 1461 void memset19_memset_multiple_times() { 1462 char *str = (char *)malloc(10 * sizeof(char)); 1463 clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}} 1464 1465 memset(str, '0', 10 * sizeof(char)); 1466 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}} 1467 // FIXME: This should be TRUE. 1468 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1469 1470 memset(str + 2, '\0', 10 * sizeof(char)); 1471 clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}} 1472 clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}} 1473 1474 free(str); 1475 } 1476 #endif 1477 1478 // The analyzer does not support binding a symbol with default binding. 1479 void memset27_symbol(char c) { 1480 char array[10] = {0}; 1481 if (c < 10) 1482 return; 1483 1484 memset(array, c, 10); 1485 1486 clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}} 1487 // FIXME: This should be TRUE. 1488 clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}} 1489 } 1490 1491 void memset28() { 1492 short x; 1493 memset(&x, 1, sizeof(short)); 1494 // This should be true. 1495 clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}} 1496 } 1497