aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-02-14 01:43:44 +0000
committerTed Kremenek <kremenek@apple.com>2009-02-14 01:43:44 +0000
commit41573ebf8fb971f40fa8a3e20648362c359b4916 (patch)
tree819d4b68e8463bfab03d015c4c894a72d4fc4d8f /lib/Analysis/CFRefCount.cpp
parent13f5f6e4796607e7bebfed1c09d9e5d4248fce9e (diff)
Static analyzer:
- Added a new 'node builder' class called GRStmtNodeBuilderRef (name may change). This is essentially a smart reference to a GRStmtNodeBuilder object that keeps track of the current context (predecessor node, GRExprEngine object, etc.) The idea is to gradually simplify the interface between GRExprEngine and GRTransferFuncs using this new builder (i.e., passing 1 argument instead of 5). It also handles some of the "auto-transition" for node creation, simplifying some of the logic in GRExprEngine itself. - Used GRStmtBuilderRef to replace GRTransferFuncs::EvalStore with GRTransferFuncs::EvalBind. The new EvalBind method will be used at any arbitrary places where a binding between a location and value takes place. Moreover, GRTransferFuncs no longer has the responsibility to request StoreManager to do the binding; this is now in GRExprEngine::EvalBind. All GRTransferFuncs::EvalBind does is checker-specific logic (which can be a no-op). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64525 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r--lib/Analysis/CFRefCount.cpp66
1 files changed, 22 insertions, 44 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 5d8e4f2bad..875c4e39b8 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -15,7 +15,7 @@
#include "GRSimpleVals.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h"
#include "clang/Analysis/PathSensitive/GRStateTrait.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/LocalCheckers.h"
@@ -1360,13 +1360,9 @@ public:
ObjCMessageExpr* ME,
ExplodedNode<GRState>* Pred);
- // Stores.
-
- virtual void EvalStore(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* E, ExplodedNode<GRState>* Pred,
- const GRState* St, SVal TargetLV, SVal Val);
+ // Stores.
+ virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
+
// End-of-path.
virtual void EvalEndPath(GRExprEngine& Engine,
@@ -1741,22 +1737,13 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
ME->arg_begin(), ME->arg_end(), Pred);
}
-// Stores.
-
-void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
- GRExprEngine& Eng,
- GRStmtNodeBuilder<GRState>& Builder,
- Expr* E, ExplodedNode<GRState>* Pred,
- const GRState* St, SVal TargetLV, SVal Val) {
-
+void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
// Check if we have a binding for "Val" and if we are storing it to something
- // we don't understand or otherwise the value "escapes" the function.
-
- if (!isa<loc::SymbolVal>(Val))
+ // we don't understand or otherwise the value "escapes" the function.
+ if (!isa<loc::SymbolVal>(val))
return;
- // Are we storing to something that causes the value to "escape"?
-
+ // Are we storing to something that causes the value to "escape"?
bool escapes = false;
// A value escapes in three possible cases (this may change):
@@ -1764,44 +1751,35 @@ void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
// (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.
-
- SymbolRef Sym = cast<loc::SymbolVal>(Val).getSymbol();
- GRStateRef state(St, Eng.getStateManager());
+ // does not understand.
+ SymbolRef Sym = cast<loc::SymbolVal>(val).getSymbol();
+ GRStateRef state = B.getState();
- if (!isa<loc::MemRegionVal>(TargetLV))
+ if (!isa<loc::MemRegionVal>(location))
escapes = true;
else {
- const MemRegion* R = cast<loc::MemRegionVal>(TargetLV).getRegion();
- escapes = !Eng.getStateManager().hasStackStorage(R);
+ const MemRegion* R = cast<loc::MemRegionVal>(location).getRegion();
+ escapes = !B.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.BindLoc(cast<Loc>(TargetLV), Val);
- escapes = (stateNew == state);
+ escapes = (state == (state.BindLoc(cast<Loc>(location), UnknownVal())));
}
}
-
- if (!escapes)
- return;
- // 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))
+ // Our store can represent the binding and we aren't storing to something
+ // that doesn't have local storage. Just return and have the simulation
+ // state continue as is. We should also just return if the tracked symbol
+ // is not associated with a reference count.
+ if (!escapes || !state.get<RefBindings>(Sym))
return;
-
- // Nuke the binding.
- state = state.remove<RefBindings>(Sym);
- // Hand of the remaining logic to the parent implementation.
- GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, state, TargetLV, Val);
+ // The tracked object excapes. Stop tracking the object.
+ B.MakeNode(state.remove<RefBindings>(Sym));
}
-// End-of-path.
-
-
std::pair<GRStateRef,bool>
CFRefCount::HandleSymbolDeath(GRStateManager& VMgr,
const GRState* St, const Decl* CD,