Refactor StoreManager::BindDecl() to take a VarRegion* instead of a VarDecl*, and modify GRExprEngine::EvalBind() to handle decl initialization as well. This paves the way for adding "checker" visitation in EvalBind().
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85983 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index d81d83c..888af9b 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -92,19 +92,17 @@
void iterBindings(Store store, BindingsHandler& f);
- const GRState *BindDecl(const GRState *state, const VarDecl *VD,
- const LocationContext *LC, SVal InitVal) {
- return state->makeWithStore(BindDeclInternal(state->getStore(),VD, LC,
+ const GRState *BindDecl(const GRState *state, const VarRegion *VR,
+ SVal InitVal) {
+ return state->makeWithStore(BindDeclInternal(state->getStore(), VR,
&InitVal));
}
- const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl *VD,
- const LocationContext *LC) {
- return state->makeWithStore(BindDeclInternal(state->getStore(), VD, LC, 0));
+ const GRState *BindDeclWithNoInit(const GRState *state, const VarRegion *VR) {
+ return state->makeWithStore(BindDeclInternal(state->getStore(), VR, 0));
}
- Store BindDeclInternal(Store store, const VarDecl *VD,
- const LocationContext *LC, SVal *InitVal);
+ Store BindDeclInternal(Store store, const VarRegion *VR, SVal *InitVal);
static inline BindingsTy GetBindings(Store store) {
return BindingsTy(static_cast<const BindingsTy::TreeTy*>(store));
@@ -532,11 +530,11 @@
return St;
}
-Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
- const LocationContext *LC,
+Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR,
SVal* InitVal) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+ const VarDecl *VD = VR->getDecl();
// BasicStore does not model arrays and structs.
if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
@@ -564,16 +562,16 @@
if (!InitVal) {
QualType T = VD->getType();
if (Loc::IsLocType(T))
- store = BindInternal(store, getLoc(VD, LC),
+ store = BindInternal(store, loc::MemRegionVal(VR),
loc::ConcreteInt(BasicVals.getValue(0, T)));
else if (T->isIntegerType())
- store = BindInternal(store, getLoc(VD, LC),
+ store = BindInternal(store, loc::MemRegionVal(VR),
nonloc::ConcreteInt(BasicVals.getValue(0, T)));
else {
// assert(0 && "ignore other types of variables");
}
} else {
- store = BindInternal(store, getLoc(VD, LC), *InitVal);
+ store = BindInternal(store, loc::MemRegionVal(VR), *InitVal);
}
}
} else {
@@ -581,7 +579,7 @@
QualType T = VD->getType();
if (ValMgr.getSymbolManager().canSymbolicate(T)) {
SVal V = InitVal ? *InitVal : UndefinedVal();
- store = BindInternal(store, getLoc(VD, LC), V);
+ store = BindInternal(store, loc::MemRegionVal(VR), V);
}
}
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 4c538c8..bf1f6ab 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -1090,21 +1090,30 @@
/// EvalBind - Handle the semantics of binding a value to a specific location.
/// This method is used by EvalStore and (soon) VisitDeclStmt, and others.
-void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
- const GRState* state, SVal location, SVal Val) {
+void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Stmt* Ex, ExplodedNode* Pred,
+ const GRState* state, SVal location, SVal Val,
+ bool atDeclInit) {
const GRState* newState = 0;
- if (location.isUnknown()) {
- // We know that the new state will be the same as the old state since
- // the location of the binding is "unknown". Consequently, there
- // is no reason to just create a new node.
- newState = state;
+ if (atDeclInit) {
+ const VarRegion *VR =
+ cast<VarRegion>(cast<loc::MemRegionVal>(location).getRegion());
+
+ newState = state->bindDecl(VR, Val);
}
else {
- // We are binding to a value other than 'unknown'. Perform the binding
- // using the StoreManager.
- newState = state->bindLoc(cast<Loc>(location), Val);
+ if (location.isUnknown()) {
+ // We know that the new state will be the same as the old state since
+ // the location of the binding is "unknown". Consequently, there
+ // is no reason to just create a new node.
+ newState = state;
+ }
+ else {
+ // We are binding to a value other than 'unknown'. Perform the binding
+ // using the StoreManager.
+ newState = state->bindLoc(cast<Loc>(location), Val);
+ }
}
// The next thing to do is check if the GRTransferFuncs object wants to
@@ -2089,18 +2098,12 @@
InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx,
Builder->getCurrentBlockCount());
}
-
- state = state->bindDecl(VD, LC, InitVal);
-
- // The next thing to do is check if the GRTransferFuncs object wants to
- // update the state based on the new binding. If the GRTransferFunc
- // object doesn't do anything, just auto-propagate the current state.
- GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, state, DS,true);
- getTF().EvalBind(BuilderRef, loc::MemRegionVal(state->getRegion(VD, LC)),
- InitVal);
+
+ EvalBind(Dst, DS, *I, state, loc::MemRegionVal(state->getRegion(VD, LC)),
+ InitVal, true);
}
else {
- state = state->bindDeclWithNoInit(VD, LC);
+ state = state->bindDeclWithNoInit(state->getRegion(VD, LC));
MakeNode(Dst, DS, *I, state);
}
}
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 5cfe4c0..dbf8c42 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -275,11 +275,11 @@
const GRState *BindCompoundLiteral(const GRState *state,
const CompoundLiteralExpr* CL, SVal V);
- const GRState *BindDecl(const GRState *ST, const VarDecl *VD,
- const LocationContext *LC, SVal InitVal);
+ const GRState *BindDecl(const GRState *ST, const VarRegion *VR,
+ SVal InitVal);
- const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl*,
- const LocationContext *) {
+ const GRState *BindDeclWithNoInit(const GRState *state,
+ const VarRegion *) {
return state;
}
@@ -1409,12 +1409,10 @@
}
const GRState *RegionStoreManager::BindDecl(const GRState *ST,
- const VarDecl *VD,
- const LocationContext *LC,
+ const VarRegion *VR,
SVal InitVal) {
- QualType T = VD->getType();
- VarRegion* VR = MRMgr.getVarRegion(VD, LC);
+ QualType T = VR->getDecl()->getType();
if (T->isArrayType())
return BindArray(ST, VR, InitVal);