diff options
author | Anna Zaks <ganna@apple.com> | 2013-04-02 01:28:24 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-04-02 01:28:24 +0000 |
commit | 60bf5f45f799f77440b52deb3fe3ddec52e0ffa0 (patch) | |
tree | d196eb387a576769795809ff7e93161637cf0d78 /clang/lib/StaticAnalyzer/Core/ProgramState.cpp | |
parent | 2832b4e8cb2da0a3d06646fb6b3d5d4a92b30364 (diff) | |
download | bcm5719-llvm-60bf5f45f799f77440b52deb3fe3ddec52e0ffa0.tar.gz bcm5719-llvm-60bf5f45f799f77440b52deb3fe3ddec52e0ffa0.zip |
[analyzer] Teach invalidateRegions that regions within LazyCompoundVal need to be invalidated
Refactor invalidateRegions to take SVals instead of Regions as input and teach RegionStore
about processing LazyCompoundVal as a top-level “escaping” value.
This addresses several false positives that get triggered by the NewDelete checker, but the
underlying issue is reproducible with other checkers as well (for example, MallocChecker).
llvm-svn: 178518
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ProgramState.cpp | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index 9aac8df0a22..ebce0c1f4d1 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -141,6 +141,7 @@ ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const { } typedef ArrayRef<const MemRegion *> RegionList; +typedef ArrayRef<SVal> ValueList; ProgramStateRef ProgramState::invalidateRegions(RegionList Regions, @@ -150,54 +151,92 @@ ProgramState::invalidateRegions(RegionList Regions, InvalidatedSymbols *IS, const CallEvent *Call, RegionList ConstRegions) const { + SmallVector<SVal, 8> Values; + for (RegionList::const_iterator I = Regions.begin(), + E = Regions.end(); I != E; ++I) + Values.push_back(loc::MemRegionVal(*I)); + + SmallVector<SVal, 8> ConstValues; + for (RegionList::const_iterator I = ConstRegions.begin(), + E = ConstRegions.end(); I != E; ++I) + ConstValues.push_back(loc::MemRegionVal(*I)); + if (!IS) { InvalidatedSymbols invalidated; - return invalidateRegionsImpl(Regions, E, Count, LCtx, + return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape, - invalidated, Call, ConstRegions); + invalidated, Call, ConstValues); } - return invalidateRegionsImpl(Regions, E, Count, LCtx, CausedByPointerEscape, - *IS, Call, ConstRegions); + return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape, + *IS, Call, ConstValues); } -ProgramStateRef -ProgramState::invalidateRegionsImpl(RegionList Regions, +ProgramStateRef +ProgramState::invalidateRegions(ValueList Values, + const Expr *E, unsigned Count, + const LocationContext *LCtx, + bool CausedByPointerEscape, + InvalidatedSymbols *IS, + const CallEvent *Call, + ValueList ConstValues) const { + if (!IS) { + InvalidatedSymbols invalidated; + return invalidateRegionsImpl(Values, E, Count, LCtx, + CausedByPointerEscape, + invalidated, Call, ConstValues); + } + return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape, + *IS, Call, ConstValues); +} + +ProgramStateRef +ProgramState::invalidateRegionsImpl(ValueList Values, const Expr *E, unsigned Count, const LocationContext *LCtx, bool CausedByPointerEscape, InvalidatedSymbols &IS, const CallEvent *Call, - RegionList ConstRegions) const { + ValueList ConstValues) const { ProgramStateManager &Mgr = getStateManager(); SubEngine* Eng = Mgr.getOwningEngine(); InvalidatedSymbols ConstIS; if (Eng) { + StoreManager::InvalidatedRegions TopLevelInvalidated; + StoreManager::InvalidatedRegions TopLevelConstInvalidated; StoreManager::InvalidatedRegions Invalidated; const StoreRef &newStore - = Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, LCtx, IS, - Call, ConstRegions, ConstIS, - &Invalidated); + = Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues, + E, Count, LCtx, Call, + IS, ConstIS, + &TopLevelInvalidated, + &TopLevelConstInvalidated, + &Invalidated); ProgramStateRef newState = makeWithStore(newStore); if (CausedByPointerEscape) { - newState = Eng->notifyCheckersOfPointerEscape(newState, - &IS, Regions, Invalidated, Call); - if (!ConstRegions.empty()) { + newState = Eng->notifyCheckersOfPointerEscape(newState, &IS, + TopLevelInvalidated, + Invalidated, Call); + if (!ConstValues.empty()) { StoreManager::InvalidatedRegions Empty; newState = Eng->notifyCheckersOfPointerEscape(newState, &ConstIS, - ConstRegions, Empty, Call, + TopLevelConstInvalidated, + Empty, Call, true); } } - return Eng->processRegionChanges(newState, &IS, Regions, Invalidated, Call); + return Eng->processRegionChanges(newState, &IS, + TopLevelInvalidated, Invalidated, + Call); } const StoreRef &newStore = - Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, LCtx, IS, - Call, ConstRegions, ConstIS, NULL); + Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues, + E, Count, LCtx, Call, + IS, ConstIS, NULL, NULL, NULL); return makeWithStore(newStore); } |