Add LocationContext* field to VarRegion. This is needed for interprocedural analysis.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79680 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index f6d3d35..65efb66 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -65,8 +65,8 @@
Store getInitialStore(const LocationContext *InitLoc);
// FIXME: Investigate what is using this. This method should be removed.
- virtual Loc getLoc(const VarDecl* VD) {
- return ValMgr.makeLoc(MRMgr.getVarRegion(VD));
+ virtual Loc getLoc(const VarDecl* VD, const LocationContext *LC) {
+ return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
}
const GRState *BindCompoundLiteral(const GRState *state,
@@ -75,12 +75,13 @@
return state;
}
- SVal getLValueVar(const GRState *state, const VarDecl* VD);
- SVal getLValueString(const GRState *state, const StringLiteral* S);
+ SVal getLValueVar(const GRState *state, const VarDecl *VD,
+ const LocationContext *LC);
+ SVal getLValueString(const GRState *state, const StringLiteral *S);
SVal getLValueCompoundLiteral(const GRState *state,
- const CompoundLiteralExpr* CL);
+ const CompoundLiteralExpr *CL);
SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
- SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D);
+ SVal getLValueField(const GRState *state, SVal Base, const FieldDecl *D);
SVal getLValueElement(const GRState *state, QualType elementType,
SVal Base, SVal Offset);
@@ -100,15 +101,19 @@
void iterBindings(Store store, BindingsHandler& f);
- const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal) {
- return state->makeWithStore(BindDeclInternal(state->getStore(),VD, &InitVal));
+ const GRState *BindDecl(const GRState *state, const VarDecl *VD,
+ const LocationContext *LC, SVal InitVal) {
+ return state->makeWithStore(BindDeclInternal(state->getStore(),VD, LC,
+ &InitVal));
}
- const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) {
- return state->makeWithStore(BindDeclInternal(state->getStore(), VD, 0));
+ const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl *VD,
+ const LocationContext *LC) {
+ return state->makeWithStore(BindDeclInternal(state->getStore(), VD, LC, 0));
}
- Store BindDeclInternal(Store store, const VarDecl* VD, SVal* InitVal);
+ Store BindDeclInternal(Store store, const VarDecl *VD,
+ const LocationContext *LC, SVal *InitVal);
static inline BindingsTy GetBindings(Store store) {
return BindingsTy(static_cast<const BindingsTy::TreeTy*>(store));
@@ -128,8 +133,9 @@
return new BasicStoreManager(StMgr);
}
-SVal BasicStoreManager::getLValueVar(const GRState *state, const VarDecl* VD) {
- return ValMgr.makeLoc(MRMgr.getVarRegion(VD));
+SVal BasicStoreManager::getLValueVar(const GRState *state, const VarDecl* VD,
+ const LocationContext *LC) {
+ return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
}
SVal BasicStoreManager::getLValueString(const GRState *state,
@@ -510,7 +516,7 @@
SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
MRMgr.getHeapRegion());
- St = BindInternal(St, ValMgr.makeLoc(MRMgr.getVarRegion(PD)),
+ St = BindInternal(St, ValMgr.makeLoc(MRMgr.getVarRegion(PD, InitLoc)),
ValMgr.makeLoc(SelfRegion));
// Scan the method for ivar references. While this requires an
@@ -526,7 +532,7 @@
// Initialize globals and parameters to symbolic values.
// Initialize local variables to undefined.
- const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD);
+ const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD, InitLoc);
SVal X = R->hasGlobalsOrParametersStorage()
? ValMgr.getRegionValueSymbolVal(R)
: UndefinedVal();
@@ -538,6 +544,7 @@
}
Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
+ const LocationContext *LC,
SVal* InitVal) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
@@ -568,16 +575,16 @@
if (!InitVal) {
QualType T = VD->getType();
if (Loc::IsLocType(T))
- store = BindInternal(store, getLoc(VD),
+ store = BindInternal(store, getLoc(VD, LC),
loc::ConcreteInt(BasicVals.getValue(0, T)));
else if (T->isIntegerType())
- store = BindInternal(store, getLoc(VD),
+ store = BindInternal(store, getLoc(VD, LC),
nonloc::ConcreteInt(BasicVals.getValue(0, T)));
else {
// assert(0 && "ignore other types of variables");
}
} else {
- store = BindInternal(store, getLoc(VD), *InitVal);
+ store = BindInternal(store, getLoc(VD, LC), *InitVal);
}
}
} else {
@@ -585,7 +592,7 @@
QualType T = VD->getType();
if (ValMgr.getSymbolManager().canSymbolicate(T)) {
SVal V = InitVal ? *InitVal : UndefinedVal();
- store = BindInternal(store, getLoc(VD), V);
+ store = BindInternal(store, getLoc(VD, LC), V);
}
}
diff --git a/lib/Analysis/BugReporterVisitors.cpp b/lib/Analysis/BugReporterVisitors.cpp
index 604542b..5c31066 100644
--- a/lib/Analysis/BugReporterVisitors.cpp
+++ b/lib/Analysis/BugReporterVisitors.cpp
@@ -314,7 +314,7 @@
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
const VarRegion *R =
- StateMgr.getRegionManager().getVarRegion(VD);
+ StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
// What did we load?
SVal V = state->getSVal(S);
diff --git a/lib/Analysis/CheckNSError.cpp b/lib/Analysis/CheckNSError.cpp
index f152d44..800940d 100644
--- a/lib/Analysis/CheckNSError.cpp
+++ b/lib/Analysis/CheckNSError.cpp
@@ -42,7 +42,8 @@
bool CheckNSErrorArgument(QualType ArgTy);
bool CheckCFErrorArgument(QualType ArgTy);
- void CheckParamDeref(VarDecl* V, const GRState *state, BugReporter& BR);
+ void CheckParamDeref(const VarDecl *V, const LocationContext *LC,
+ const GRState *state, BugReporter& BR);
void EmitRetTyWarning(BugReporter& BR, const Decl& CodeDecl);
@@ -94,8 +95,7 @@
// Scan the parameters for an implicit null dereference.
for (llvm::SmallVectorImpl<VarDecl*>::iterator I=ErrorParams.begin(),
E=ErrorParams.end(); I!=E; ++I)
- CheckParamDeref(*I, (*RI)->getState(), BR);
-
+ CheckParamDeref(*I, (*RI)->getLocationContext(), (*RI)->getState(), BR);
}
}
@@ -191,10 +191,12 @@
return TT->getDecl()->getIdentifier() == II;
}
-void NSErrorCheck::CheckParamDeref(VarDecl* Param, const GRState *rootState,
+void NSErrorCheck::CheckParamDeref(const VarDecl *Param,
+ const LocationContext *LC,
+ const GRState *rootState,
BugReporter& BR) {
- SVal ParamL = rootState->getLValue(Param);
+ SVal ParamL = rootState->getLValue(Param, LC);
const MemRegion* ParamR = cast<loc::MemRegionVal>(ParamL).getRegionAs<VarRegion>();
assert (ParamR && "Parameters always have VarRegions.");
SVal ParamSVal = rootState->getSVal(ParamR);
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 3f59ba6..a8d3407 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -215,7 +215,7 @@
const ParmVarDecl *PD = FD->getParamDecl(0);
QualType T = PD->getType();
if (T->isIntegerType())
- if (const MemRegion *R = state->getRegion(PD)) {
+ if (const MemRegion *R = state->getRegion(PD, InitLoc)) {
SVal V = state->getSVal(loc::MemRegionVal(R));
SVal Constraint = EvalBinOp(state, BinaryOperator::GT, V,
ValMgr.makeZeroVal(T),
@@ -967,8 +967,8 @@
// Transfer functions: Loads and stores.
//===----------------------------------------------------------------------===//
-void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue) {
+void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst, bool asLValue) {
const GRState* state = GetState(Pred);
@@ -976,7 +976,7 @@
if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
- SVal V = state->getLValue(VD);
+ SVal V = state->getLValue(VD, Pred->getLocationContext());
if (asLValue)
MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V),
@@ -1781,7 +1781,7 @@
if (DeclStmt* DS = dyn_cast<DeclStmt>(elem)) {
VarDecl* ElemD = cast<VarDecl>(DS->getSingleDecl());
assert (ElemD->getInit() == 0);
- ElementV = GetState(Pred)->getLValue(ElemD);
+ ElementV = GetState(Pred)->getLValue(ElemD, Pred->getLocationContext());
VisitObjCForCollectionStmtAux(S, Pred, Dst, ElementV);
return;
}
@@ -2130,7 +2130,8 @@
}
}
-void GRExprEngine::VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
+void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
+ ExplodedNodeSet& Dst) {
// The CFG has one DeclStmt per Decl.
Decl* D = *DS->decl_begin();
@@ -2188,6 +2189,8 @@
}
// Decls without InitExpr are not initialized explicitly.
+ const LocationContext *LC = (*I)->getLocationContext();
+
if (InitEx) {
SVal InitVal = state->getSVal(InitEx);
QualType T = VD->getType();
@@ -2199,17 +2202,17 @@
InitVal = ValMgr.getConjuredSymbolVal(InitEx, Count);
}
- state = state->bindDecl(VD, InitVal);
+ 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)),
+ getTF().EvalBind(BuilderRef, loc::MemRegionVal(state->getRegion(VD, LC)),
InitVal);
}
else {
- state = state->bindDeclWithNoInit(VD);
+ state = state->bindDeclWithNoInit(VD, LC);
MakeNode(Dst, DS, *I, state);
}
}
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index ac63306..2aacbf9 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -98,6 +98,10 @@
DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
}
+void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+ VarRegion::ProfileRegion(ID, getDecl(), LC, superRegion);
+}
+
void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
const MemRegion *sreg) {
ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
@@ -249,8 +253,9 @@
return getRegion<StringRegion>(Str);
}
-VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
- return getRegion<VarRegion>(d);
+VarRegion* MemRegionManager::getVarRegion(const VarDecl* D,
+ const LocationContext *LC) {
+ return getRegion<VarRegion>(D, LC);
}
CompoundLiteralRegion*
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 518978c..13768ec 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -204,7 +204,8 @@
/// getLValueVar - Returns an SVal that represents the lvalue of a
/// variable. Within RegionStore a variable has an associated
/// VarRegion, and the lvalue of the variable is the lvalue of that region.
- SVal getLValueVar(const GRState *state, const VarDecl* VD);
+ SVal getLValueVar(const GRState *ST, const VarDecl *VD,
+ const LocationContext *LC);
SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
@@ -243,7 +244,7 @@
if (MD->getSelfDecl() == PD) {
SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
MRMgr.getHeapRegion());
- B = RBFactory.Add(B, MRMgr.getVarRegion(PD),
+ B = RBFactory.Add(B, MRMgr.getVarRegion(PD, InitLoc),
ValMgr.makeLoc(SelfRegion));
}
}
@@ -280,9 +281,11 @@
const GRState *BindCompoundLiteral(const GRState *state,
const CompoundLiteralExpr* CL, SVal V);
- const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal);
+ const GRState *BindDecl(const GRState *ST, const VarDecl *VD,
+ const LocationContext *LC, SVal InitVal);
- const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) {
+ const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl*,
+ const LocationContext *) {
return state;
}
@@ -547,8 +550,9 @@
/// getLValueVar - Returns an SVal that represents the lvalue of a
/// variable. Within RegionStore a variable has an associated
/// VarRegion, and the lvalue of the variable is the lvalue of that region.
-SVal RegionStoreManager::getLValueVar(const GRState *St, const VarDecl* VD) {
- return loc::MemRegionVal(MRMgr.getVarRegion(VD));
+SVal RegionStoreManager::getLValueVar(const GRState *ST, const VarDecl *VD,
+ const LocationContext *LC) {
+ return loc::MemRegionVal(MRMgr.getVarRegion(VD, LC));
}
/// getLValueCompoundLiteral - Returns an SVal representing the lvalue
@@ -1345,18 +1349,20 @@
return state->makeWithStore(RBFactory.Add(B, R, V).getRoot());
}
-const GRState *RegionStoreManager::BindDecl(const GRState *state,
- const VarDecl* VD, SVal InitVal) {
+const GRState *RegionStoreManager::BindDecl(const GRState *ST,
+ const VarDecl *VD,
+ const LocationContext *LC,
+ SVal InitVal) {
QualType T = VD->getType();
- VarRegion* VR = MRMgr.getVarRegion(VD);
+ VarRegion* VR = MRMgr.getVarRegion(VD, LC);
if (T->isArrayType())
- return BindArray(state, VR, InitVal);
+ return BindArray(ST, VR, InitVal);
if (T->isStructureType())
- return BindStruct(state, VR, InitVal);
+ return BindStruct(ST, VR, InitVal);
- return Bind(state, ValMgr.makeLoc(VR), InitVal);
+ return Bind(ST, ValMgr.makeLoc(VR), InitVal);
}
// FIXME: this method should be merged into Bind().