aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ProgramState.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-03-20 20:35:53 +0000
committerJordan Rose <jordan_rose@apple.com>2013-03-20 20:35:53 +0000
commitf8ddc098981d4d85cad4e72fc6dfcfe83b842b66 (patch)
treef03f97abd1fd285147db499e1c4379d961cdc49a /lib/StaticAnalyzer/Core/ProgramState.cpp
parente1a2e90876cbe2187250939374d26036ccba2ad6 (diff)
[analyzer] Invalidate regions indirectly accessible through const pointers.
In this case, the value of 'x' may be changed after the call to indirectAccess: struct Wrapper { int *ptr; }; void indirectAccess(const Wrapper &w); void test() { int x = 42; Wrapper w = { x }; clang_analyzer_eval(x == 42); // TRUE indirectAccess(w); clang_analyzer_eval(x == 42); // UNKNOWN } This is important for modelling return-by-value objects in C++, to show that the contents of the struct are escaping in the return copy-constructor. <rdar://problem/13239826> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177570 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 64205f8d99..3e47dcef2b 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -140,30 +140,34 @@ ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
new_state;
}
+typedef ArrayRef<const MemRegion *> RegionList;
+
ProgramStateRef
-ProgramState::invalidateRegions(ArrayRef<const MemRegion *> Regions,
+ProgramState::invalidateRegions(RegionList Regions,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
bool CausedByPointerEscape,
InvalidatedSymbols *IS,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ RegionList ConstRegions) const {
if (!IS) {
InvalidatedSymbols invalidated;
return invalidateRegionsImpl(Regions, E, Count, LCtx,
CausedByPointerEscape,
- invalidated, Call);
+ invalidated, Call, ConstRegions);
}
return invalidateRegionsImpl(Regions, E, Count, LCtx, CausedByPointerEscape,
- *IS, Call);
+ *IS, Call, ConstRegions);
}
ProgramStateRef
-ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
+ProgramState::invalidateRegionsImpl(RegionList Regions,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
bool CausedByPointerEscape,
InvalidatedSymbols &IS,
- const CallEvent *Call) const {
+ const CallEvent *Call,
+ RegionList ConstRegions) const {
ProgramStateManager &Mgr = getStateManager();
SubEngine* Eng = Mgr.getOwningEngine();
@@ -171,7 +175,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
StoreManager::InvalidatedRegions Invalidated;
const StoreRef &newStore
= Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, LCtx, IS,
- Call, &Invalidated);
+ Call, ConstRegions, &Invalidated);
ProgramStateRef newState = makeWithStore(newStore);
@@ -184,7 +188,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
const StoreRef &newStore =
Mgr.StoreMgr->invalidateRegions(getStore(), Regions, E, Count, LCtx, IS,
- Call, NULL);
+ Call, ConstRegions, NULL);
return makeWithStore(newStore);
}