diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-10-20 01:20:57 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-10-20 01:20:57 +0000 |
commit | ab22ee9ede5532f35c64b8eaccb4210f3f16397d (patch) | |
tree | e28c5e641cea3fbf9218c93eaca0546004a38162 | |
parent | e9731832ec3b995defba821ec24343d74d004f9f (diff) |
RegionStore: Use the *default* binding (instead of the *direct* binding) of an Objective-C object
region when doing lazy value retrieval of an ivar.
This fixes: <rdar://problem/7312221>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84584 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 6 | ||||
-rw-r--r-- | test/Analysis/misc-ps-region-store.m | 69 |
2 files changed, 72 insertions, 3 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 35eb5b7019..780772a6f1 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -1244,8 +1244,8 @@ SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state, const MemRegion *superR = R->getSuperRegion(); - // Check if the super region has a binding. - if (Optional<SVal> V = getDirectBinding(B, superR)) { + // Check if the super region has a default binding. + if (Optional<SVal> V = getDefaultBinding(B, superR)) { if (SymbolRef parentSym = V->getAsSymbol()) return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R); @@ -1792,7 +1792,7 @@ GRState const *RegionStoreManager::EnterStackFrame(GRState const *state, void RegionStoreManager::print(Store store, llvm::raw_ostream& OS, const char* nl, const char *sep) { RegionBindings B = GetRegionBindings(store); - OS << "Store (direct bindings):" << nl; + OS << "Store (direct and default bindings):" << nl; for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) OS << ' ' << I.getKey() << " : " << I.getData() << nl; diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index e849042b3d..b6fff102a7 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -141,9 +141,11 @@ again: } } +//===----------------------------------------------------------------------===// // Reduced test case from <rdar://problem/7114618>. // Basically a null check is performed on the field value, which is then // assigned to a variable and then checked again. +//===----------------------------------------------------------------------===// struct s_7114618 { int *p; }; void test_rdar_7114618(struct s_7114618 *s) { if (s->p) { @@ -168,9 +170,11 @@ void f() { } } +//===----------------------------------------------------------------------===// // <rdar://problem/7185607> // Bit-fields of a struct should be invalidated when blasting the entire // struct with an integer constant. +//===----------------------------------------------------------------------===// struct test_7185607 { int x : 10; int y : 22; @@ -181,9 +185,11 @@ int rdar_test_7185607() { return s.x; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/7242006> [RegionStore] compound literal assignment with // floats not honored // This test case is mirrored in misc-ps.m, but this case is a negative. +//===----------------------------------------------------------------------===// typedef float CGFloat; typedef struct _NSSize { CGFloat width; @@ -195,9 +201,11 @@ CGFloat rdar7242006_negative(CGFloat x) { return y.width; // expected-warning{{garbage}} } +//===----------------------------------------------------------------------===// // <rdar://problem/7249340> - Allow binding of values to symbolic regions. // This test case shows how RegionStore tracks the value bound to 'x' // after the assignment. +//===----------------------------------------------------------------------===// typedef int* ptr_rdar_7249340; void rdar_7249340(ptr_rdar_7249340 x) { *x = 1; @@ -207,11 +215,13 @@ void rdar_7249340(ptr_rdar_7249340 x) { *p = 0xDEADBEEF; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/7249327> - This test case tests both value tracking of // array values and that we handle symbolic values that are casted // between different integer types. Note the assignment 'n = *a++'; here // 'n' is and 'int' and '*a' is 'unsigned'. Previously we got a false positive // at 'x += *b++' (undefined value) because we got a false path. +//===----------------------------------------------------------------------===// int rdar_7249327_aux(void); void rdar_7249327(unsigned int A[2*32]) { @@ -237,8 +247,10 @@ void rdar_7249327(unsigned int A[2*32]) { x += *b++; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/6914474> - Check that 'x' is invalidated because its // address is passed in as a value to a struct. +//===----------------------------------------------------------------------===// struct doodad_6914474 { int *v; }; extern void prod_6914474(struct doodad_6914474 *d); int rdar_6914474(void) { @@ -278,8 +290,11 @@ int test_handle_array_wrapper() { return p->z; // no-warning } +//===----------------------------------------------------------------------===// // <rdar://problem/7261075> [RegionStore] crash when // handling load: '*((unsigned int *)"????")' +//===----------------------------------------------------------------------===// + int rdar_7261075(void) { unsigned int var = 0; if (var == *((unsigned int *)"????")) @@ -287,8 +302,11 @@ int rdar_7261075(void) { return 0; } +//===----------------------------------------------------------------------===// // <rdar://problem/7275774> false path due to limited pointer // arithmetic constraints +//===----------------------------------------------------------------------===// + void rdar_7275774(void *data, unsigned n) { if (!(data || n == 0)) return; @@ -303,3 +321,54 @@ void rdar_7275774(void *data, unsigned n) { } } +//===----------------------------------------------------------------------===// +// <rdar://problem/7312221> +// +// Test that Objective-C instance variables aren't prematurely pruned +// from the analysis state. +//===----------------------------------------------------------------------===// + +struct rdar_7312221_value { int x; }; + +@interface RDar7312221 +{ + struct rdar_7312221_value *y; +} +- (void) doSomething_7312221; +@end + +extern struct rdar_7312221_value *rdar_7312221_helper(); +extern int rdar_7312221_helper_2(id o); +extern void rdar_7312221_helper_3(int z); + +@implementation RDar7312221 +- (void) doSomething_7312221 { + if (y == 0) { + y = rdar_7312221_helper(); + if (y != 0) { + y->x = rdar_7312221_helper_2(self); + // The following use of 'y->x' previously triggered a null dereference, as the value of 'y' + // before 'y = rdar_7312221_helper()' would be used. + rdar_7312221_helper_3(y->x); // no-warning + } + } +} +@end + +struct rdar_7312221_container { + struct rdar_7312221_value *y; +}; + +extern int rdar_7312221_helper_4(struct rdar_7312221_container *s); + +// This test case essentially matches the one in [RDar7312221 doSomething_7312221]. +void doSomething_7312221_with_struct(struct rdar_7312221_container *Self) { + if (Self->y == 0) { + Self->y = rdar_7312221_helper(); + if (Self->y != 0) { + Self->y->x = rdar_7312221_helper_4(Self); + rdar_7312221_helper_3(Self->y->x); // no-warning + } + } +} + |