misc-ps-region-store.m revision e030358cc06e1cbce3c2e00ca67c946f9164b2a8
1// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s 2// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s 3 4typedef struct objc_selector *SEL; 5typedef signed char BOOL; 6typedef int NSInteger; 7typedef unsigned int NSUInteger; 8typedef struct _NSZone NSZone; 9@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 10@protocol NSObject - (BOOL)isEqual:(id)object; @end 11@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end 12@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end 13@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end 14@interface NSObject <NSObject> {} - (id)init; @end 15extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); 16@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> 17- (NSUInteger)length; 18+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; 19@end extern NSString * const NSBundleDidLoadNotification; 20@interface NSAssertionHandler : NSObject {} 21+ (NSAssertionHandler *)currentHandler; 22- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; 23@end 24extern NSString * const NSConnectionReplyMode; 25 26#ifdef TEST_64 27typedef long long int64_t; 28typedef int64_t intptr_t; 29#else 30typedef int int32_t; 31typedef int32_t intptr_t; 32#endif 33 34//--------------------------------------------------------------------------- 35// Test case 'checkaccess_union' differs for region store and basic store. 36// The basic store doesn't reason about compound literals, so the code 37// below won't fire an "uninitialized value" warning. 38//--------------------------------------------------------------------------- 39 40// PR 2948 (testcase; crash on VisitLValue for union types) 41// http://llvm.org/bugs/show_bug.cgi?id=2948 42void checkaccess_union() { 43 int ret = 0, status; 44 // Since RegionStore doesn't handle unions yet, 45 // this branch condition won't be triggered 46 // as involving an uninitialized value. 47 if (((((__extension__ (((union { // no-warning 48 __typeof (status) __in; int __i;} 49 ) 50 { 51 .__in = (status)} 52 ).__i))) & 0xff00) >> 8) == 1) 53 ret = 1; 54} 55 56// Check our handling of fields being invalidated by function calls. 57struct test2_struct { int x; int y; char* s; }; 58void test2_help(struct test2_struct* p); 59 60char test2() { 61 struct test2_struct s; 62 test2_help(&s); 63 char *p = 0; 64 65 if (s.x > 1) { 66 if (s.s != 0) { 67 p = "hello"; 68 } 69 } 70 71 if (s.x > 1) { 72 if (s.s != 0) { 73 return *p; 74 } 75 } 76 77 return 'a'; 78} 79 80// BasicStore handles this case incorrectly because it doesn't reason about 81// the value pointed to by 'x' and thus creates different symbolic values 82// at the declarations of 'a' and 'b' respectively. RegionStore handles 83// it correctly. See the companion test in 'misc-ps-basic-store.m'. 84void test_trivial_symbolic_comparison_pointer_parameter(int *x) { 85 int a = *x; 86 int b = *x; 87 if (a != b) { 88 int *p = 0; 89 *p = 0xDEADBEEF; // no-warning 90 } 91} 92 93// This is a modified test from 'misc-ps.m'. Here we have the extra 94// NULL dereferences which are pruned out by RegionStore's symbolic reasoning 95// of fields. 96typedef struct _BStruct { void *grue; } BStruct; 97void testB_aux(void *ptr); 98 99void testB(BStruct *b) { 100 { 101 int *__gruep__ = ((int *)&((b)->grue)); 102 int __gruev__ = *__gruep__; 103 int __gruev2__ = *__gruep__; 104 if (__gruev__ != __gruev2__) { 105 int *p = 0; 106 *p = 0xDEADBEEF; // no-warning 107 } 108 109 testB_aux(__gruep__); 110 } 111 { 112 int *__gruep__ = ((int *)&((b)->grue)); 113 int __gruev__ = *__gruep__; 114 int __gruev2__ = *__gruep__; 115 if (__gruev__ != __gruev2__) { 116 int *p = 0; 117 *p = 0xDEADBEEF; // no-warning 118 } 119 120 if (~0 != __gruev__) {} 121 } 122} 123 124void testB_2(BStruct *b) { 125 { 126 int **__gruep__ = ((int **)&((b)->grue)); 127 int *__gruev__ = *__gruep__; 128 testB_aux(__gruep__); 129 } 130 { 131 int **__gruep__ = ((int **)&((b)->grue)); 132 int *__gruev__ = *__gruep__; 133 if ((int*)~0 != __gruev__) {} 134 } 135} 136 137// This test case is a reduced case of a caching bug discovered by an 138// assertion failure in RegionStoreManager::BindArray. Essentially the 139// DeclStmt is evaluated twice, but on the second loop iteration the 140// engine caches out. Previously a false transition would cause UnknownVal 141// to bind to the variable, firing an assertion failure. This bug was fixed 142// in r76262. 143void test_declstmt_caching() { 144again: 145 { 146 const char a[] = "I like to crash"; 147 goto again; 148 } 149} 150 151//===----------------------------------------------------------------------===// 152// Reduced test case from <rdar://problem/7114618>. 153// Basically a null check is performed on the field value, which is then 154// assigned to a variable and then checked again. 155//===----------------------------------------------------------------------===// 156struct s_7114618 { int *p; }; 157void test_rdar_7114618(struct s_7114618 *s) { 158 if (s->p) { 159 int *p = s->p; 160 if (!p) { 161 // Infeasible 162 int *dead = 0; 163 *dead = 0xDEADBEEF; // no-warning 164 } 165 } 166} 167 168// Test pointers increment correctly. 169void f() { 170 int a[2]; 171 a[1] = 3; 172 int *p = a; 173 p++; 174 if (*p != 3) { 175 int *q = 0; 176 *q = 3; // no-warning 177 } 178} 179 180//===----------------------------------------------------------------------===// 181// <rdar://problem/7185607> 182// Bit-fields of a struct should be invalidated when blasting the entire 183// struct with an integer constant. 184//===----------------------------------------------------------------------===// 185struct test_7185607 { 186 int x : 10; 187 int y : 22; 188}; 189int rdar_test_7185607() { 190 struct test_7185607 s; // Uninitialized. 191 *((unsigned *) &s) = 0U; 192 return s.x; // no-warning 193} 194 195//===----------------------------------------------------------------------===// 196// <rdar://problem/7242006> [RegionStore] compound literal assignment with 197// floats not honored 198// This test case is mirrored in misc-ps.m, but this case is a negative. 199//===----------------------------------------------------------------------===// 200typedef float CGFloat; 201typedef struct _NSSize { 202 CGFloat width; 203 CGFloat height; 204} NSSize; 205 206CGFloat rdar7242006_negative(CGFloat x) { 207 NSSize y; 208 return y.width; // expected-warning{{garbage}} 209} 210 211//===----------------------------------------------------------------------===// 212// <rdar://problem/7249340> - Allow binding of values to symbolic regions. 213// This test case shows how RegionStore tracks the value bound to 'x' 214// after the assignment. 215//===----------------------------------------------------------------------===// 216typedef int* ptr_rdar_7249340; 217void rdar_7249340(ptr_rdar_7249340 x) { 218 *x = 1; 219 if (*x) 220 return; 221 int *p = 0; // This is unreachable. 222 *p = 0xDEADBEEF; // no-warning 223} 224 225//===----------------------------------------------------------------------===// 226// <rdar://problem/7249327> - This test case tests both value tracking of 227// array values and that we handle symbolic values that are casted 228// between different integer types. Note the assignment 'n = *a++'; here 229// 'n' is and 'int' and '*a' is 'unsigned'. Previously we got a false positive 230// at 'x += *b++' (undefined value) because we got a false path. 231//===----------------------------------------------------------------------===// 232int rdar_7249327_aux(void); 233 234void rdar_7249327(unsigned int A[2*32]) { 235 int B[2*32]; 236 int *b; 237 unsigned int *a; 238 int x = 0; 239 240 int n; 241 242 a = A; 243 b = B; 244 245 n = *a++; 246 if (n) 247 *b++ = rdar_7249327_aux(); 248 249 a = A; 250 b = B; 251 252 n = *a++; 253 if (n) 254 x += *b++; // no-warning 255} 256 257//===----------------------------------------------------------------------===// 258// <rdar://problem/6914474> - Check that 'x' is invalidated because its 259// address is passed in as a value to a struct. 260//===----------------------------------------------------------------------===// 261struct doodad_6914474 { int *v; }; 262extern void prod_6914474(struct doodad_6914474 *d); 263int rdar_6914474(void) { 264 int x; 265 struct doodad_6914474 d; 266 d.v = &x; 267 prod_6914474(&d); 268 return x; // no-warning 269} 270 271// Test invalidation of a single field. 272struct s_test_field_invalidate { 273 int x; 274}; 275extern void test_invalidate_field(int *x); 276int test_invalidate_field_test() { 277 struct s_test_field_invalidate y; 278 test_invalidate_field(&y.x); 279 return y.x; // no-warning 280} 281int test_invalidate_field_test_positive() { 282 struct s_test_field_invalidate y; 283 return y.x; // expected-warning{{garbage}} 284} 285 286// This test case illustrates how a typeless array of bytes casted to a 287// struct should be treated as initialized. RemoveDeadBindings previously 288// had a bug that caused 'x' to lose its default symbolic value after the 289// assignment to 'p', thus causing 'p->z' to evaluate to "undefined". 290struct ArrayWrapper { unsigned char y[16]; }; 291struct WrappedStruct { unsigned z; }; 292 293int test_handle_array_wrapper() { 294 struct ArrayWrapper x; 295 test_handle_array_wrapper(&x); 296 struct WrappedStruct *p = (struct WrappedStruct*) x.y; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}} 297 return p->z; // no-warning 298} 299 300//===----------------------------------------------------------------------===// 301// <rdar://problem/7261075> [RegionStore] crash when 302// handling load: '*((unsigned int *)"????")' 303//===----------------------------------------------------------------------===// 304 305int rdar_7261075(void) { 306 unsigned int var = 0; 307 if (var == *((unsigned int *)"????")) 308 return 1; 309 return 0; 310} 311 312//===----------------------------------------------------------------------===// 313// <rdar://problem/7275774> false path due to limited pointer 314// arithmetic constraints 315//===----------------------------------------------------------------------===// 316 317void rdar_7275774(void *data, unsigned n) { 318 if (!(data || n == 0)) 319 return; 320 321 unsigned short *p = (unsigned short*) data; 322 unsigned short *q = p + (n / 2); 323 324 if (p < q) { 325 // If we reach here, 'p' cannot be null. If 'p' is null, then 'n' must 326 // be '0', meaning that this branch is not feasible. 327 *p = *q; // no-warning 328 } 329} 330 331//===----------------------------------------------------------------------===// 332// <rdar://problem/7312221> 333// 334// Test that Objective-C instance variables aren't prematurely pruned 335// from the analysis state. 336//===----------------------------------------------------------------------===// 337 338struct rdar_7312221_value { int x; }; 339 340@interface RDar7312221 341{ 342 struct rdar_7312221_value *y; 343} 344- (void) doSomething_7312221; 345@end 346 347extern struct rdar_7312221_value *rdar_7312221_helper(); 348extern int rdar_7312221_helper_2(id o); 349extern void rdar_7312221_helper_3(int z); 350 351@implementation RDar7312221 352- (void) doSomething_7312221 { 353 if (y == 0) { 354 y = rdar_7312221_helper(); 355 if (y != 0) { 356 y->x = rdar_7312221_helper_2(self); 357 // The following use of 'y->x' previously triggered a null dereference, as the value of 'y' 358 // before 'y = rdar_7312221_helper()' would be used. 359 rdar_7312221_helper_3(y->x); // no-warning 360 } 361 } 362} 363@end 364 365struct rdar_7312221_container { 366 struct rdar_7312221_value *y; 367}; 368 369extern int rdar_7312221_helper_4(struct rdar_7312221_container *s); 370 371// This test case essentially matches the one in [RDar7312221 doSomething_7312221]. 372void doSomething_7312221_with_struct(struct rdar_7312221_container *Self) { 373 if (Self->y == 0) { 374 Self->y = rdar_7312221_helper(); 375 if (Self->y != 0) { 376 Self->y->x = rdar_7312221_helper_4(Self); 377 rdar_7312221_helper_3(Self->y->x); // no-warning 378 } 379 } 380} 381 382//===----------------------------------------------------------------------===// 383// <rdar://problem/7332673> - Just more tests cases for regions 384//===----------------------------------------------------------------------===// 385 386void rdar_7332673_test1() { 387 char value[1]; 388 if ( *(value) != 1 ) {} // expected-warning{{The left operand of '!=' is a garbage value}} 389} 390int rdar_7332673_test2_aux(char *x); 391void rdar_7332673_test2() { 392 char *value; 393 if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Pass-by-value argument in function call is undefined}} 394} 395 396//===----------------------------------------------------------------------===// 397// <rdar://problem/7347252>: Because of a bug in 398// RegionStoreManager::RemoveDeadBindings(), the symbol for s->session->p 399// would incorrectly be pruned from the state after the call to 400// rdar7347252_malloc1(), and would incorrectly result in a warning about 401// passing a null pointer to rdar7347252_memcpy(). 402//===----------------------------------------------------------------------===// 403 404struct rdar7347252_AA { char *p;}; 405typedef struct { 406 struct rdar7347252_AA *session; 407 int t; 408 char *q; 409} rdar7347252_SSL1; 410 411int rdar7347252_f(rdar7347252_SSL1 *s); 412char *rdar7347252_malloc1(int); 413char *rdar7347252_memcpy1(char *d, char *s, int n) __attribute__((nonnull (1,2))); 414 415int rdar7347252(rdar7347252_SSL1 *s) { 416 rdar7347252_f(s); // the SymbolicRegion of 's' is set a default binding of conjured symbol 417 if (s->session->p == ((void*)0)) { 418 if ((s->session->p = rdar7347252_malloc1(10)) == ((void*)0)) { 419 return 0; 420 } 421 rdar7347252_memcpy1(s->session->p, "aa", 2); // no-warning 422 } 423 return 0; 424} 425 426//===----------------------------------------------------------------------===// 427// PR 5316 - "crash when accessing field of lazy compound value" 428// Previously this caused a crash at the MemberExpr '.chr' when loading 429// a field value from a LazyCompoundVal 430//===----------------------------------------------------------------------===// 431 432typedef unsigned int pr5316_wint_t; 433typedef pr5316_wint_t pr5316_REFRESH_CHAR; 434typedef struct { 435 pr5316_REFRESH_CHAR chr; 436} 437pr5316_REFRESH_ELEMENT; 438static void pr5316(pr5316_REFRESH_ELEMENT *dst, const pr5316_REFRESH_ELEMENT *src) { 439 while ((*dst++ = *src++).chr != L'\0') ; 440} 441 442//===----------------------------------------------------------------------===// 443// Exercise creating ElementRegion with symbolic super region. 444//===----------------------------------------------------------------------===// 445void element_region_with_symbolic_superregion(int* p) { 446 int *x; 447 int a; 448 if (p[0] == 1) 449 x = &a; 450 if (p[0] == 1) 451 (void)*x; // no-warning 452} 453 454//===----------------------------------------------------------------------===// 455// Test returning an out-of-bounds pointer (CWE-466) 456//===----------------------------------------------------------------------===// 457 458static int test_cwe466_return_outofbounds_pointer_a[10]; 459int *test_cwe466_return_outofbounds_pointer() { 460 int *p = test_cwe466_return_outofbounds_pointer_a+10; 461 return p; // expected-warning{{Returned pointer value points outside the original object}} 462} 463 464//===----------------------------------------------------------------------===// 465// PR 3135 - Test case that shows that a variable may get invalidated when its 466// address is included in a structure that is passed-by-value to an unknown function. 467//===----------------------------------------------------------------------===// 468 469typedef struct { int *a; } pr3135_structure; 470int pr3135_bar(pr3135_structure *x); 471int pr3135() { 472 int x; 473 pr3135_structure y = { &x }; 474 // the call to pr3135_bar may initialize x 475 if (pr3135_bar(&y) && x) // no-warning 476 return 1; 477 return 0; 478} 479 480//===----------------------------------------------------------------------===// 481// <rdar://problem/7403269> - Test that we handle compound initializers with 482// partially unspecified array values. Previously this caused a crash. 483//===----------------------------------------------------------------------===// 484 485typedef struct RDar7403269 { 486 unsigned x[10]; 487 unsigned y; 488} RDar7403269; 489 490void rdar7403269() { 491 RDar7403269 z = { .y = 0 }; 492 if (z.x[4] == 0) 493 return; 494 int *p = 0; 495 *p = 0xDEADBEEF; // no-warning 496} 497 498typedef struct RDar7403269_b { 499 struct zorg { int w; int k; } x[10]; 500 unsigned y; 501} RDar7403269_b; 502 503void rdar7403269_b() { 504 RDar7403269_b z = { .y = 0 }; 505 if (z.x[5].w == 0) 506 return; 507 int *p = 0; 508 *p = 0xDEADBEEF; // no-warning 509} 510 511void rdar7403269_b_pos() { 512 RDar7403269_b z = { .y = 0 }; 513 if (z.x[5].w == 1) 514 return; 515 int *p = 0; 516 *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} 517} 518 519 520//===----------------------------------------------------------------------===// 521// Test that incrementing a non-null pointer results in a non-null pointer. 522// (<rdar://problem/7191542>) 523//===----------------------------------------------------------------------===// 524 525void test_increment_nonnull_rdar_7191542(const char *path) { 526 const char *alf = 0; 527 528 for (;;) { 529 // When using basic-store, we get a null dereference here because we lose information 530 // about path after the pointer increment. 531 char c = *path++; // no-warning 532 if (c == 'a') { 533 alf = path; 534 } 535 536 if (alf) 537 return; 538 } 539} 540 541//===----------------------------------------------------------------------===// 542// Test that the store (implicitly) tracks values for doubles/floats that are 543// uninitialized (<rdar://problem/6811085>) 544//===----------------------------------------------------------------------===// 545 546double rdar_6811085(void) { 547 double u; 548 return u + 10; // expected-warning{{The left operand of '+' is a garbage value}} 549} 550 551//===----------------------------------------------------------------------===// 552// Path-sensitive tests for blocks. 553//===----------------------------------------------------------------------===// 554 555void indirect_block_call(void (^f)()); 556 557int blocks_1(int *p, int z) { 558 __block int *q = 0; 559 void (^bar)() = ^{ q = p; }; 560 561 if (z == 1) { 562 // The call to 'bar' might cause 'q' to be invalidated. 563 bar(); 564 *q = 0x1; // no-warning 565 } 566 else if (z == 2) { 567 // The function 'indirect_block_call' might invoke bar, thus causing 568 // 'q' to possibly be invalidated. 569 indirect_block_call(bar); 570 *q = 0x1; // no-warning 571 } 572 else { 573 *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} 574 } 575 return z; 576} 577 578int blocks_2(int *p, int z) { 579 int *q = 0; 580 void (^bar)(int **) = ^(int **r){ *r = p; }; 581 582 if (z) { 583 // The call to 'bar' might cause 'q' to be invalidated. 584 bar(&q); 585 *q = 0x1; // no-warning 586 } 587 else { 588 *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} 589 } 590 return z; 591} 592 593//===----------------------------------------------------------------------===// 594// <rdar://problem/7462324> - Test that variables passed using __blocks 595// are not treated as being uninitialized. 596//===----------------------------------------------------------------------===// 597 598typedef void (^RDar_7462324_Callback)(id obj); 599 600@interface RDar7462324 601- (void) foo:(id)target; 602- (void) foo_positive:(id)target; 603 604@end 605 606@implementation RDar7462324 607- (void) foo:(id)target { 608 __block RDar_7462324_Callback builder = ((void*) 0); 609 builder = ^(id object) { 610 if (object) { 611 builder(self); // no-warning 612 } 613 }; 614 builder(target); 615} 616- (void) foo_positive:(id)target { 617 __block RDar_7462324_Callback builder = ((void*) 0); 618 builder = ^(id object) { 619 id x; 620 if (object) { 621 builder(x); // expected-warning{{Pass-by-value argument in function call is undefined}} 622 } 623 }; 624 builder(target); 625} 626@end 627 628//===----------------------------------------------------------------------===// 629// <rdar://problem/7468209> - Scanning for live variables within a block should 630// not crash on variables passed by reference via __block. 631//===----------------------------------------------------------------------===// 632 633int rdar7468209_aux(); 634void rdar7468209_aux_2(); 635 636void rdar7468209() { 637 __block int x = 0; 638 ^{ 639 x = rdar7468209_aux(); 640 // We need a second statement so that 'x' would be removed from the store if it wasn't 641 // passed by reference. 642 rdar7468209_aux_2(); 643 }(); 644} 645 646//===----------------------------------------------------------------------===// 647// PR 5857 - Test loading an integer from a byte array that has also been 648// reinterpreted to be loaded as a field. 649//===----------------------------------------------------------------------===// 650 651typedef struct { int x; } TestFieldLoad; 652int pr5857(char *src) { 653 TestFieldLoad *tfl = (TestFieldLoad *) (intptr_t) src; 654 int y = tfl->x; 655 long long *z = (long long *) (intptr_t) src; 656 long long w = 0; 657 int n = 0; 658 for (n = 0; n < y; ++n) { 659 // Previously we crashed analyzing this statement. 660 w = *z++; 661 } 662 return 1; 663} 664 665//===----------------------------------------------------------------------===// 666// PR 4358 - Without field-sensitivity, this code previously triggered 667// a false positive that 'uninit' could be uninitialized at the call 668// to pr4358_aux(). 669//===----------------------------------------------------------------------===// 670 671struct pr4358 { 672 int bar; 673 int baz; 674}; 675void pr4358_aux(int x); 676void pr4358(struct pr4358 *pnt) { 677 int uninit; 678 if (pnt->bar < 3) { 679 uninit = 1; 680 } else if (pnt->baz > 2) { 681 uninit = 3; 682 } else if (pnt->baz <= 2) { 683 uninit = 2; 684 } 685 pr4358_aux(uninit); // no-warning 686} 687