// Utility methods for getting regions.
//==---------------------------------------------------------------------==//
- const VarRegion* getRegion(const VarDecl* D) const;
+ const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
const MemRegion* getSelfRegion() const;
return bindExpr(Ex, V, true, false);
}
- const GRState *bindDecl(const VarDecl* VD, SVal IVal) const;
+ const GRState *bindDecl(const VarDecl *VD, const LocationContext *LC,
+ SVal V) const;
- const GRState *bindDeclWithNoInit(const VarDecl* VD) const;
+ const GRState *bindDeclWithNoInit(const VarDecl *VD,
+ const LocationContext *LC) const;
const GRState *bindLoc(Loc location, SVal V) const;
const GRState *unbindLoc(Loc LV) const;
/// Get the lvalue for a variable reference.
- SVal getLValue(const VarDecl *decl) const;
+ SVal getLValue(const VarDecl *D, const LocationContext *LC) const;
/// Get the lvalue for a StringLiteral.
SVal getLValue(const StringLiteral *literal) const;
// Out-of-line method definitions for GRState.
//===----------------------------------------------------------------------===//
-inline const VarRegion* GRState::getRegion(const VarDecl* D) const {
- return Mgr->getRegionManager().getVarRegion(D);
+inline const VarRegion* GRState::getRegion(const VarDecl *D,
+ const LocationContext *LC) const {
+ return Mgr->getRegionManager().getVarRegion(D, LC);
}
inline const MemRegion* GRState::getSelfRegion() const {
return Mgr->StoreMgr->BindCompoundLiteral(this, CL, V);
}
-inline const GRState *GRState::bindDecl(const VarDecl* VD, SVal IVal) const {
- return Mgr->StoreMgr->BindDecl(this, VD, IVal);
+inline const GRState *GRState::bindDecl(const VarDecl* VD,
+ const LocationContext *LC,
+ SVal IVal) const {
+ return Mgr->StoreMgr->BindDecl(this, VD, LC, IVal);
}
-inline const GRState *GRState::bindDeclWithNoInit(const VarDecl* VD) const {
- return Mgr->StoreMgr->BindDeclWithNoInit(this, VD);
+inline const GRState *GRState::bindDeclWithNoInit(const VarDecl* VD,
+ const LocationContext *LC) const {
+ return Mgr->StoreMgr->BindDeclWithNoInit(this, VD, LC);
}
inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
}
-inline SVal GRState::getLValue(const VarDecl* VD) const {
- return Mgr->StoreMgr->getLValueVar(this, VD);
+inline SVal GRState::getLValue(const VarDecl* VD,
+ const LocationContext *LC) const {
+ return Mgr->StoreMgr->getLValueVar(this, VD, LC);
}
inline SVal GRState::getLValue(const StringLiteral *literal) const {
namespace clang {
class MemRegionManager;
-class MemSpaceRegion;
+class MemSpaceRegion;
+class LocationContext;
//===----------------------------------------------------------------------===//
// Base region classes.
class VarRegion : public DeclRegion {
friend class MemRegionManager;
+
+ // Data.
+ const LocationContext *LC;
- VarRegion(const VarDecl* vd, const MemRegion* sReg)
- : DeclRegion(vd, sReg, VarRegionKind) {}
+ // Constructors and private methods.
+ VarRegion(const VarDecl* vd, const LocationContext *lC, const MemRegion* sReg)
+ : DeclRegion(vd, sReg, VarRegionKind), LC(lC) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
- const MemRegion* superRegion) {
+ const LocationContext *LC,
+ const MemRegion *superRegion) {
DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
+ ID.AddPointer(LC);
}
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
public:
- const VarDecl* getDecl() const { return cast<VarDecl>(D); }
+ const VarDecl *getDecl() const { return cast<VarDecl>(D); }
+
+ const LocationContext *getLocationContext() const { return LC; }
QualType getValueType(ASTContext& C) const {
// FIXME: We can cache this if needed.
StringRegion* getStringRegion(const StringLiteral* Str);
/// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl.
- VarRegion* getVarRegion(const VarDecl* vd);
+ /// a specified VarDecl and LocationContext.
+ VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
/// getElementRegion - Retrieve the memory region associated with the
/// associated element type, index, and super region.
ElementRegion *getElementRegion(QualType elementType, SVal Idx,
- const MemRegion* superRegion,ASTContext &Ctx);
+ const MemRegion *superRegion,
+ ASTContext &Ctx);
ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
const MemRegion *superRegion) {
template <> struct MemRegionManagerTrait<VarRegion> {
typedef MemRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const VarDecl *d) {
- if (d->hasLocalStorage()) {
- return isa<ParmVarDecl>(d) || isa<ImplicitParamDecl>(d)
+ static const SuperRegionTy* getSuperRegion(MemRegionManager &MRMgr,
+ const VarDecl *D,
+ const LocationContext *LC) {
+
+ // FIXME: Make stack regions have a location context?
+
+ if (D->hasLocalStorage()) {
+ return isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion();
}
// caller's responsibility to 'delete' the returned map.
virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0;
- virtual SVal getLValueVar(const GRState *state, const VarDecl *vd) = 0;
+ virtual SVal getLValueVar(const GRState *ST, const VarDecl *VD,
+ const LocationContext *LC) = 0;
virtual SVal getLValueString(const GRState *state,
const StringLiteral* sl) = 0;
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
- virtual const GRState *BindDecl(const GRState *state, const VarDecl *vd,
- SVal initVal) = 0;
+ virtual const GRState *BindDecl(const GRState *ST, const VarDecl *VD,
+ const LocationContext *LC, SVal initVal) = 0;
- virtual const GRState *BindDeclWithNoInit(const GRState *state,
- const VarDecl *vd) = 0;
+ virtual const GRState *BindDeclWithNoInit(const GRState *ST,
+ const VarDecl *VD,
+ const LocationContext *LC) = 0;
virtual const GRState *InvalidateRegion(const GRState *state,
const MemRegion *R,
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,
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);
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));
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,
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
// 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();
}
Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
+ const LocationContext *LC,
SVal* InitVal) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
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 {
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);
}
}
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);
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);
// 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);
}
}
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);
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),
// 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);
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),
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;
}
}
}
-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();
}
// Decls without InitExpr are not initialized explicitly.
+ const LocationContext *LC = (*I)->getLocationContext();
+
if (InitEx) {
SVal InitVal = state->getSVal(InitEx);
QualType T = VD->getType();
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);
}
}
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);
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*
/// 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);
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));
}
}
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;
}
/// 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
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().