diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2012-08-08 18:23:27 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-08 18:23:27 +0000 |
| commit | 3a80cec5e92da70064541f1d11222e2e5c2d4e8c (patch) | |
| tree | 99f34000219bf358bb9e979c3eb509189457c10b /clang/lib/StaticAnalyzer/Core/ProgramState.cpp | |
| parent | 55edf5ff14525faf6ffec12a397601c5f2b0db2d (diff) | |
| download | bcm5719-llvm-3a80cec5e92da70064541f1d11222e2e5c2d4e8c.tar.gz bcm5719-llvm-3a80cec5e92da70064541f1d11222e2e5c2d4e8c.zip | |
[analyzer] Revamp RegionStore to distinguish regions with symbolic offsets.
RegionStore currently uses a (Region, Offset) pair to describe the locations
of memory bindings. However, this representation breaks down when we have
regions like 'array[index]', where 'index' is unknown. We used to store this
as (SubRegion, 0); now we mark them specially as (SubRegion, SYMBOLIC).
Furthermore, ProgramState::scanReachableSymbols depended on the existence of
a sub-region map, but RegionStore's implementation doesn't provide for such
a thing. Moving the store-traversing logic of scanReachableSymbols into the
StoreManager allows us to eliminate the notion of SubRegionMap altogether.
This fixes some particularly awkward broken test cases, now in
array-struct-region.c.
llvm-svn: 161510
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ProgramState.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ProgramState.cpp | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index c916c1a0207..9245a70dd2b 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -499,8 +499,6 @@ ProgramStateRef ProgramStateManager::removeGDM(ProgramStateRef state, void *Key) return getPersistentState(NewState); } -void ScanReachableSymbols::anchor() { } - bool ScanReachableSymbols::scan(nonloc::CompoundVal val) { for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I) if (!scan(*I)) @@ -578,10 +576,19 @@ bool ScanReachableSymbols::scan(const MemRegion *R) { return false; // If this is a subregion, also visit the parent regions. - if (const SubRegion *SR = dyn_cast<SubRegion>(R)) - if (!scan(SR->getSuperRegion())) + if (const SubRegion *SR = dyn_cast<SubRegion>(R)) { + const MemRegion *Super = SR->getSuperRegion(); + if (!scan(Super)) return false; + // When we reach the topmost region, scan all symbols in it. + if (isa<MemSpaceRegion>(Super)) { + StoreManager &StoreMgr = state->getStateManager().getStoreManager(); + if (!StoreMgr.scanReachableSymbols(state->getStore(), SR, *this)) + return false; + } + } + // Regions captured by a block are also implicitly reachable. if (const BlockDataRegion *BDR = dyn_cast<BlockDataRegion>(R)) { BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(), @@ -592,16 +599,7 @@ bool ScanReachableSymbols::scan(const MemRegion *R) { } } - // Now look at the binding to this region (if any). - if (!scan(state->getSValAsScalarOrLoc(R))) - return false; - - // Now look at the subregions. - if (!SRM.get()) - SRM.reset(state->getStateManager().getStoreManager(). - getSubRegionMap(state->getStore())); - - return SRM->iterSubRegions(R, *this); + return true; } bool ProgramState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const { |

