diff options
-rw-r--r-- | lib/Checker/RegionStore.cpp | 18 | ||||
-rw-r--r-- | test/Analysis/misc-ps.m | 20 |
2 files changed, 34 insertions, 4 deletions
diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index 95d082ee44..231be0af18 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -686,6 +686,16 @@ void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) { B = RM.Add(B, baseR, BindingKey::Default, V); return; } + + if (includeGlobals && + isa<NonStaticGlobalSpaceRegion>(baseR->getMemorySpace())) { + // If the region is a global and we are invalidating all globals, + // just erase the entry. This causes all globals to be lazily + // symbolicated from the same base symbol. + B = RM.Remove(B, baseR); + return; + } + DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count); assert(SymbolManager::canSymbolicate(T) || V.isUnknown()); @@ -1182,16 +1192,16 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store, RegionBindings B = GetRegionBindings(store); while (superR) { - if (const Optional<SVal> &D = RetrieveDerivedDefaultValue(B, superR, R, Ty)) + if (const Optional<SVal> &D = + RetrieveDerivedDefaultValue(B, superR, R, Ty)) return *D; // If our super region is a field or element itself, walk up the region // hierarchy to see if there is a default value installed in an ancestor. - if (isa<FieldRegion>(superR) || isa<ElementRegion>(superR)) { - superR = cast<SubRegion>(superR)->getSuperRegion(); + if (const SubRegion *SR = dyn_cast<SubRegion>(superR)) { + superR = SR->getSuperRegion(); continue; } - break; } diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 52dd7e1def..12e51023a9 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1159,3 +1159,23 @@ void __PR8458(PR8458 *x) { @synchronized(x.lock) {} // no-warning } +// PR 8440 - False null dereference during store to array-in-field-in-global. +// This test case previously resulted in a bogus null deref warning from +// incorrect lazy symbolication logic in RegionStore. +static struct { + int num; + char **data; +} saved_pr8440; + +char *foo_pr8440(); +char **bar_pr8440(); +void baz_pr8440(int n) +{ + saved_pr8440.num = n; + if (saved_pr8440.data) + return; + saved_pr8440.data = bar_pr8440(); + for (int i = 0 ; i < n ; i ++) + saved_pr8440.data[i] = foo_pr8440(); // no-warning +} + |