aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-10-18 03:49:51 +0000
committerTed Kremenek <kremenek@apple.com>2008-10-18 03:49:51 +0000
commita496d169d392dfb44c0bde4708247ab775d44b61 (patch)
treeeaf622786b02d6dc0bb6050f5b09ab01d59e0cb6 /lib/Analysis/CFRefCount.cpp
parent5c456fe4d354dab9e8a1309aefe828ea7b6d6f26 (diff)
retain/release checker: Check if a tracked value escapes if we also try binding it to the store and the store doesn't support that binding (i.e., it cannot track it). This has the nice feature that the checker will automatically get more powerful if we use a more powerful store model.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57755 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r--lib/Analysis/CFRefCount.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 23613d1320..e98a6db316 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1727,20 +1727,36 @@ void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
bool escapes = false;
+ // A value escapes in three possible cases (this may change):
+ //
+ // (1) we are binding to something that is not a memory region.
+ // (2) we are binding to a memregion that does not have stack storage
+ // (3) we are binding to a memregion with stack storage that the store
+ // does not understand.
+
+ SymbolID Sym = cast<loc::SymbolVal>(Val).getSymbol();
+ GRStateRef state(St, Eng.getStateManager());
+
if (!isa<loc::MemRegionVal>(TargetLV))
escapes = true;
else {
const MemRegion* R = cast<loc::MemRegionVal>(TargetLV).getRegion();
escapes = !Eng.getStateManager().hasStackStorage(R);
+
+ if (!escapes) {
+ // To test (3), generate a new state with the binding removed. If it is
+ // the same state, then it escapes (since the store cannot represent
+ // the binding).
+ GRStateRef stateNew = state.SetSVal(cast<Loc>(TargetLV), Val);
+ escapes = (stateNew == state);
+ }
}
if (!escapes)
return;
-
- SymbolID Sym = cast<loc::SymbolVal>(Val).getSymbol();
-
- GRStateRef state(St, Eng.getStateManager());
-
+
+ // Do we have a reference count binding?
+ // FIXME: Is this step even needed? We do blow away the binding anyway.
if (!state.get<RefBindings>(Sym))
return;