#ifndef LLVM_CLANG_ANALYSIS_STORE_H
#define LLVM_CLANG_ANALYSIS_STORE_H
-#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Analysis/PathSensitive/MemRegion.h"
+#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Analysis/PathSensitive/ValueManager.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include <iosfwd>
StoreManager(GRStateManager &stateMgr);
protected:
- virtual const GRState* AddRegionView(const GRState* St,
- const MemRegion* View,
- const MemRegion* Base) {
- return St;
+ virtual const GRState *AddRegionView(const GRState *state,
+ const MemRegion *view,
+ const MemRegion *base) {
+ return state;
}
public:
/// expected type of the returned value. This is used if the value is
/// lazily computed.
/// \return The value bound to the location \c loc.
- virtual SVal Retrieve(const GRState* state, Loc loc,
+ virtual SVal Retrieve(const GRState *state, Loc loc,
QualType T = QualType()) = 0;
/// Return a state with the specified value bound to the given location.
/// \return A pointer to a GRState object that contains the same bindings as
/// \c state with the addition of having the value specified by \c val bound
/// to the location given for \c loc.
- virtual const GRState* Bind(const GRState* state, Loc loc, SVal val) = 0;
+ virtual const GRState *Bind(const GRState *state, Loc loc, SVal val) = 0;
virtual Store Remove(Store St, Loc L) = 0;
/// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
- virtual const GRState* BindCompoundLiteral(const GRState* St,
- const CompoundLiteralExpr* CL,
- SVal V) = 0;
+ virtual const GRState *BindCompoundLiteral(const GRState *state,
+ const CompoundLiteralExpr* cl,
+ SVal v) = 0;
/// getInitialStore - Returns the initial "empty" store representing the
/// value bindings upon entry to an analyzed function.
/// getSubRegionMap - Returns an opaque map object that clients can query
/// to get the subregions of a given MemRegion object. It is the
// caller's responsibility to 'delete' the returned map.
- virtual SubRegionMap* getSubRegionMap(const GRState *state) = 0;
+ virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0;
- virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0;
+ virtual SVal getLValueVar(const GRState *state, const VarDecl *vd) = 0;
- virtual SVal getLValueString(const GRState* St, const StringLiteral* S) = 0;
+ virtual SVal getLValueString(const GRState *state,
+ const StringLiteral* sl) = 0;
- virtual SVal getLValueCompoundLiteral(const GRState* St,
- const CompoundLiteralExpr* CL) = 0;
+ virtual SVal getLValueCompoundLiteral(const GRState *state,
+ const CompoundLiteralExpr* cl) = 0;
- virtual SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
- SVal Base) = 0;
+ virtual SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* decl,
+ SVal base) = 0;
- virtual SVal getLValueField(const GRState* St, SVal Base,
+ virtual SVal getLValueField(const GRState *state, SVal base,
const FieldDecl* D) = 0;
- virtual SVal getLValueElement(const GRState* St, QualType elementType,
- SVal Base, SVal Offset) = 0;
+ virtual SVal getLValueElement(const GRState *state, QualType elementType,
+ SVal base, SVal offset) = 0;
- virtual SVal getSizeInElements(const GRState* St, const MemRegion* R) {
+ // FIXME: Make out-of-line.
+ virtual SVal getSizeInElements(const GRState *state, const MemRegion *region){
return UnknownVal();
}
/// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
virtual SVal ArrayToPointer(Loc Array) = 0;
-
class CastResult {
- const GRState* State;
- const MemRegion* R;
+ const GRState *state;
+ const MemRegion *region;
public:
- const GRState* getState() const { return State; }
- const MemRegion* getRegion() const { return R; }
- CastResult(const GRState* s, const MemRegion* r = 0) : State(s), R(r) {}
+ const GRState *getState() const { return state; }
+ const MemRegion* getRegion() const { return region; }
+ CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){}
};
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
/// a MemRegion* to a specific location type. 'R' is the region being
/// casted and 'CastToTy' the result type of the cast.
- virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
+ virtual CastResult CastRegion(const GRState *state, const MemRegion *region,
QualType CastToTy);
/// EvalBinOp - Perform pointer arithmetic.
- virtual SVal EvalBinOp(const GRState *state,
- BinaryOperator::Opcode Op, Loc L, NonLoc R) {
+ virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,
+ Loc lhs, NonLoc rhs) {
return UnknownVal();
}
/// method returns NULL.
virtual const MemRegion* getSelfRegion(Store store) = 0;
- virtual Store
- RemoveDeadBindings(const GRState* state, Stmt* Loc, SymbolReaper& SymReaper,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
+ virtual Store RemoveDeadBindings(const GRState *state,
+ Stmt* Loc, SymbolReaper& SymReaper,
+ llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
- virtual const GRState* BindDecl(const GRState* St, const VarDecl* VD,
- SVal InitVal) = 0;
+ virtual const GRState *BindDecl(const GRState *state, const VarDecl *vd,
+ SVal initVal) = 0;
- virtual const GRState* BindDeclWithNoInit(const GRState* St,
- const VarDecl* VD) = 0;
+ virtual const GRState *BindDeclWithNoInit(const GRState *state,
+ const VarDecl *vd) = 0;
- virtual const GRState* setExtent(const GRState* St,
- const MemRegion* R, SVal Extent) {
- return St;
+ // FIXME: Make out-of-line.
+ virtual const GRState *setExtent(const GRState *state,
+ const MemRegion *region, SVal extent) {
+ return state;
}
- virtual const GRState* setDefaultValue(const GRState* St,
- const MemRegion* R, SVal V) {
- return St;
+ // FIXME: Make out-of-line.
+ virtual const GRState *setDefaultValue(const GRState *state,
+ const MemRegion *region,
+ SVal val) {
+ return state;
}
virtual void print(Store store, std::ostream& Out,
public:
virtual ~BindingsHandler();
virtual bool HandleBinding(StoreManager& SMgr, Store store,
- const MemRegion* R, SVal val) = 0;
+ const MemRegion *region, SVal val) = 0;
};
/// iterBindings - Iterate over the bindings in the Store.
virtual void iterBindings(Store store, BindingsHandler& f) = 0;
};
+// FIXME: Do we still need this?
/// SubRegionMap - An abstract interface that represents a queryable map
/// between MemRegion objects and their subregions.
class SubRegionMap {
virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
};
- virtual bool iterSubRegions(const MemRegion* R, Visitor& V) const = 0;
+ virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0;
};
-
+
+// FIXME: Do we need to pass GRStateManager anymore?
StoreManager *CreateBasicStoreManager(GRStateManager& StMgr);
StoreManager *CreateRegionStoreManager(GRStateManager& StMgr);
StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr);
-
+
} // end clang namespace
#endif
~BasicStoreManager() {}
- SubRegionMap* getSubRegionMap(const GRState *state) {
+ SubRegionMap *getSubRegionMap(const GRState *state) {
return new BasicStoreSubRegionMap();
}
SVal Retrieve(const GRState *state, Loc loc, QualType T = QualType());
- const GRState* Bind(const GRState* St, Loc L, SVal V) {
- Store store = BindInternal(St->getStore(), L, V);
- return StateMgr.MakeStateWithStore(St, store);
+ const GRState *Bind(const GRState *state, Loc L, SVal V) {
+ return state->makeWithStore(BindInternal(state->getStore(), L, V));
}
Store scanForIvars(Stmt *B, const Decl* SelfDecl, Store St);
return Loc::MakeVal(MRMgr.getVarRegion(VD));
}
- const GRState* BindCompoundLiteral(const GRState* St,
- const CompoundLiteralExpr* CL,
- SVal V) {
- return St;
+ const GRState *BindCompoundLiteral(const GRState *state,
+ const CompoundLiteralExpr* cl,
+ SVal val) {
+ return state;
}
- SVal getLValueVar(const GRState* St, const VarDecl* VD);
- SVal getLValueString(const GRState* St, const StringLiteral* S);
- SVal getLValueCompoundLiteral(const GRState* St,
+ SVal getLValueVar(const GRState *state, const VarDecl* VD);
+ SVal getLValueString(const GRState *state, const StringLiteral* S);
+ SVal getLValueCompoundLiteral(const GRState *state,
const CompoundLiteralExpr* CL);
- SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base);
- SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D);
- SVal getLValueElement(const GRState* St, QualType elementType,
+ SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
+ SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D);
+ SVal getLValueElement(const GRState *state, QualType elementType,
SVal Base, SVal Offset);
/// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
const MemRegion* getSelfRegion(Store) { return SelfRegion; }
/// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
- /// It returns a new Store with these values removed, and populates LSymbols
- /// and DSymbols with the known set of live and dead symbols respectively.
- Store
- RemoveDeadBindings(const GRState* state, Stmt* Loc,
+ /// It returns a new Store with these values removed.
+ Store RemoveDeadBindings(const GRState *state, Stmt* Loc,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
void iterBindings(Store store, BindingsHandler& f);
- const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal) {
- Store store = BindDeclInternal(St->getStore(), VD, &InitVal);
- return StateMgr.MakeStateWithStore(St, store);
+ const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal) {
+ return state->makeWithStore(BindDeclInternal(state->getStore(),VD, &InitVal));
}
- const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
- Store store = BindDeclInternal(St->getStore(), VD, 0);
- return StateMgr.MakeStateWithStore(St, store);
+ const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) {
+ return state->makeWithStore(BindDeclInternal(state->getStore(), VD, 0));
}
Store BindDeclInternal(Store store, const VarDecl* VD, SVal* InitVal);
return new BasicStoreManager(StMgr);
}
-SVal BasicStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) {
+SVal BasicStoreManager::getLValueVar(const GRState *state, const VarDecl* VD) {
return Loc::MakeVal(MRMgr.getVarRegion(VD));
}
-SVal BasicStoreManager::getLValueString(const GRState* St,
+SVal BasicStoreManager::getLValueString(const GRState *state,
const StringLiteral* S) {
return Loc::MakeVal(MRMgr.getStringRegion(S));
}
-SVal BasicStoreManager::getLValueCompoundLiteral(const GRState* St,
+SVal BasicStoreManager::getLValueCompoundLiteral(const GRState *state,
const CompoundLiteralExpr* CL){
return Loc::MakeVal(MRMgr.getCompoundLiteralRegion(CL));
}
-SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
+SVal BasicStoreManager::getLValueIvar(const GRState *state, const ObjCIvarDecl* D,
SVal Base) {
if (Base.isUnknownOrUndef())
return UnknownVal();
}
-SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base,
+SVal BasicStoreManager::getLValueField(const GRState *state, SVal Base,
const FieldDecl* D) {
if (Base.isUnknownOrUndef())
return Loc::MakeVal(MRMgr.getFieldRegion(D, BaseR));
}
-SVal BasicStoreManager::getLValueElement(const GRState* St,
+SVal BasicStoreManager::getLValueElement(const GRState *state,
QualType elementType,
SVal Base, SVal Offset) {
}
}
-SVal BasicStoreManager::Retrieve(const GRState* state, Loc loc, QualType T) {
+SVal BasicStoreManager::Retrieve(const GRState *state, Loc loc, QualType T) {
if (isa<UnknownVal>(loc))
return UnknownVal();
}
Store
-BasicStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
+BasicStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
{
SubRegionMap* getSubRegionMap(const GRState *state);
- const GRState* BindCompoundLiteral(const GRState* St,
- const CompoundLiteralExpr* CL, SVal V);
-
/// getLValueString - Returns an SVal representing the lvalue of a
/// StringLiteral. Within RegionStore a StringLiteral has an
/// associated StringRegion, and the lvalue of a StringLiteral is
/// the lvalue of that region.
- SVal getLValueString(const GRState* St, const StringLiteral* S);
+ SVal getLValueString(const GRState *state, const StringLiteral* S);
/// getLValueCompoundLiteral - Returns an SVal representing the
/// lvalue of a compound literal. Within RegionStore a compound
/// literal has an associated region, and the lvalue of the
/// compound literal is the lvalue of that region.
- SVal getLValueCompoundLiteral(const GRState* St, const CompoundLiteralExpr*);
+ SVal getLValueCompoundLiteral(const GRState *state, const CompoundLiteralExpr*);
/// 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* St, const VarDecl* VD);
+ SVal getLValueVar(const GRState *state, const VarDecl* VD);
- SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base);
+ SVal getLValueIvar(const GRState *state, const ObjCIvarDecl* D, SVal Base);
- SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D);
+ SVal getLValueField(const GRState *state, SVal Base, const FieldDecl* D);
- SVal getLValueFieldOrIvar(const GRState* St, SVal Base, const Decl* D);
+ SVal getLValueFieldOrIvar(const GRState *state, SVal Base, const Decl* D);
- SVal getLValueElement(const GRState* St, QualType elementType,
+ SVal getLValueElement(const GRState *state, QualType elementType,
SVal Base, SVal Offset);
- SVal getSizeInElements(const GRState* St, const MemRegion* R);
/// ArrayToPointer - Emulates the "decay" of an array to a pointer
/// type. 'Array' represents the lvalue of the array being decayed
/// casts from arrays to pointers.
SVal ArrayToPointer(Loc Array);
- CastResult CastRegion(const GRState* state, const MemRegion* R,
+ CastResult CastRegion(const GRState *state, const MemRegion* R,
QualType CastToTy);
- SVal EvalBinOp(const GRState *state,BinaryOperator::Opcode Op,Loc L,NonLoc R);
+ SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,Loc L,NonLoc R);
- /// The high level logic for this method is this:
- /// Retrieve (L)
- /// if L has binding
- /// return L's binding
- /// else if L is in killset
- /// return unknown
- /// else
- /// if L is on stack or heap
- /// return undefined
- /// else
- /// return symbolic
- SVal Retrieve(const GRState* state, Loc L, QualType T = QualType());
- const GRState* Bind(const GRState* St, Loc LV, SVal V);
- Store Remove(Store store, Loc LV);
Store getInitialStore() { return RBFactory.GetEmptyMap().getRoot(); }
return SelfRegion;
}
- /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values.
- /// It returns a new Store with these values removed, and populates LSymbols
- // and DSymbols with the known set of live and dead symbols respectively.
- Store RemoveDeadBindings(const GRState* state, Stmt* Loc,
- SymbolReaper& SymReaper,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
- const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal);
+
+ //===-------------------------------------------------------------------===//
+ // Binding values to regions.
+ //===-------------------------------------------------------------------===//
- const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
- return St;
- }
+ const GRState *Bind(const GRState *state, Loc LV, SVal V);
- const GRState* setExtent(const GRState* St, const MemRegion* R, SVal Extent);
- const GRState* setCastType(const GRState* St, const MemRegion* R, QualType T);
+ const GRState *BindCompoundLiteral(const GRState *state,
+ const CompoundLiteralExpr* CL, SVal V);
+
+ const GRState *BindDecl(const GRState *state, const VarDecl* VD, SVal InitVal);
- static inline RegionBindingsTy GetRegionBindings(Store store) {
- return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
+ const GRState *BindDeclWithNoInit(const GRState *state, const VarDecl* VD) {
+ return state;
}
- void print(Store store, std::ostream& Out, const char* nl, const char *sep);
+ /// BindStruct - Bind a compound value to a structure.
+ const GRState *BindStruct(const GRState *, const TypedRegion* R, SVal V);
+
+ const GRState *BindArray(const GRState *state, const TypedRegion* R, SVal V);
+
+ /// KillStruct - Set the entire struct to unknown.
+ const GRState *KillStruct(const GRState *state, const TypedRegion* R);
- void iterBindings(Store store, BindingsHandler& f) {
- // FIXME: Implement.
- }
- const GRState* setDefaultValue(const GRState* St, const MemRegion* R, SVal V);
-private:
- const GRState* BindArray(const GRState* St, const TypedRegion* R, SVal V);
+ const GRState *setDefaultValue(const GRState *state, const MemRegion* R, SVal V);
+ Store Remove(Store store, Loc LV);
+
+ //===------------------------------------------------------------------===//
+ // Loading values from regions.
+ //===------------------------------------------------------------------===//
+
+ /// The high level logic for this method is this:
+ /// Retrieve (L)
+ /// if L has binding
+ /// return L's binding
+ /// else if L is in killset
+ /// return unknown
+ /// else
+ /// if L is on stack or heap
+ /// return undefined
+ /// else
+ /// return symbolic
+ SVal Retrieve(const GRState *state, Loc L, QualType T = QualType());
+
/// Retrieve the values in a struct and return a CompoundVal, used when doing
/// struct copy:
/// struct s x, y;
/// x = y;
/// y's value is retrieved by this method.
- SVal RetrieveStruct(const GRState* St, const TypedRegion* R);
+ SVal RetrieveStruct(const GRState *St, const TypedRegion* R);
+
+ SVal RetrieveArray(const GRState *St, const TypedRegion* R);
+
+ //===------------------------------------------------------------------===//
+ // State pruning.
+ //===------------------------------------------------------------------===//
+
+ /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values.
+ /// It returns a new Store with these values removed.
+ Store RemoveDeadBindings(const GRState *state, Stmt* Loc, SymbolReaper& SymReaper,
+ llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
- SVal RetrieveArray(const GRState* St, const TypedRegion* R);
+ //===------------------------------------------------------------------===//
+ // Region "extents".
+ //===------------------------------------------------------------------===//
+
+ const GRState *setExtent(const GRState *state, const MemRegion* R, SVal Extent);
+ SVal getSizeInElements(const GRState *state, const MemRegion* R);
- const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V);
+ //===------------------------------------------------------------------===//
+ // Region "views".
+ //===------------------------------------------------------------------===//
+
+ const GRState *AddRegionView(const GRState *state, const MemRegion* View,
+ const MemRegion* Base);
- /// KillStruct - Set the entire struct to unknown.
- const GRState* KillStruct(const GRState* St, const TypedRegion* R);
+ const GRState *RemoveRegionView(const GRState *state, const MemRegion* View,
+ const MemRegion* Base);
+ //===------------------------------------------------------------------===//
// Utility methods.
- BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
- ASTContext& getContext() { return StateMgr.getContext(); }
+ //===------------------------------------------------------------------===//
+
+ const GRState *setCastType(const GRState *state, const MemRegion* R, QualType T);
+
+ static inline RegionBindingsTy GetRegionBindings(Store store) {
+ return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
+ }
+
+ void print(Store store, std::ostream& Out, const char* nl, const char *sep);
- SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
+ void iterBindings(Store store, BindingsHandler& f) {
+ // FIXME: Implement.
+ }
- const GRState* AddRegionView(const GRState* St,
- const MemRegion* View, const MemRegion* Base);
- const GRState* RemoveRegionView(const GRState* St,
- const MemRegion* View, const MemRegion* Base);
+ // FIXME: Remove.
+ BasicValueFactory& getBasicVals() {
+ return StateMgr.getBasicVals();
+ }
+
+ // FIXME: Remove.
+ ASTContext& getContext() { return StateMgr.getContext(); }
+
+ // FIXME: Use ValueManager?
+ SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
};
} // end anonymous namespace
/// StringLiteral. Within RegionStore a StringLiteral has an
/// associated StringRegion, and the lvalue of a StringLiteral is the
/// lvalue of that region.
-SVal RegionStoreManager::getLValueString(const GRState* St,
+SVal RegionStoreManager::getLValueString(const GRState *St,
const StringLiteral* S) {
return loc::MemRegionVal(MRMgr.getStringRegion(S));
}
/// 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) {
+SVal RegionStoreManager::getLValueVar(const GRState *St, const VarDecl* VD) {
return loc::MemRegionVal(MRMgr.getVarRegion(VD));
}
/// has an associated region, and the lvalue of the compound literal
/// is the lvalue of that region.
SVal
-RegionStoreManager::getLValueCompoundLiteral(const GRState* St,
+RegionStoreManager::getLValueCompoundLiteral(const GRState *St,
const CompoundLiteralExpr* CL) {
return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL));
}
-SVal RegionStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
+SVal RegionStoreManager::getLValueIvar(const GRState *St, const ObjCIvarDecl* D,
SVal Base) {
return getLValueFieldOrIvar(St, Base, D);
}
-SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base,
+SVal RegionStoreManager::getLValueField(const GRState *St, SVal Base,
const FieldDecl* D) {
return getLValueFieldOrIvar(St, Base, D);
}
-SVal RegionStoreManager::getLValueFieldOrIvar(const GRState* St, SVal Base,
+SVal RegionStoreManager::getLValueFieldOrIvar(const GRState *St, SVal Base,
const Decl* D) {
if (Base.isUnknownOrUndef())
return Base;
return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
}
-SVal RegionStoreManager::getLValueElement(const GRState* St,
+SVal RegionStoreManager::getLValueElement(const GRState *St,
QualType elementType,
SVal Base, SVal Offset) {
// Extents for regions.
//===----------------------------------------------------------------------===//
-SVal RegionStoreManager::getSizeInElements(const GRState* St,
+SVal RegionStoreManager::getSizeInElements(const GRState *state,
const MemRegion* R) {
if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
// Get the type of the variable.
return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false);
}
- GRStateRef state(St, StateMgr);
- const QualType* CastTy = state.get<RegionCasts>(VR);
+ const QualType* CastTy = state->get<RegionCasts>(VR);
// If the VarRegion is cast to other type, compute the size with respect to
// that type.
return UnknownVal();
}
-const GRState* RegionStoreManager::setExtent(const GRState* St,
- const MemRegion* R, SVal Extent) {
- GRStateRef state(St, StateMgr);
- return state.set<RegionExtents>(R, Extent);
+const GRState *RegionStoreManager::setExtent(const GRState *state,
+ const MemRegion *region,
+ SVal extent) {
+ return state->set<RegionExtents>(region, extent);
}
//===----------------------------------------------------------------------===//
}
RegionStoreManager::CastResult
-RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
+RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R,
QualType CastToTy) {
ASTContext& Ctx = StateMgr.getContext();
}
else if (const AllocaRegion *AR = dyn_cast<AllocaRegion>(MR)) {
// Get the alloca region's current cast type.
- GRStateRef StRef(state, StateMgr);
- GRStateTrait<RegionCasts>::lookup_type T = StRef.get<RegionCasts>(AR);
+
+ GRStateTrait<RegionCasts>::lookup_type T = state->get<RegionCasts>(AR);
assert(T && "alloca region has no type.");
QualType EleTy = cast<PointerType>(T->getTypePtr())->getPointeeType();
SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
// Loading values from regions.
//===----------------------------------------------------------------------===//
-SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
+SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
+
assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined");
if (isa<loc::ConcreteInt>(L))
return UndefinedVal();
- const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
+ const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
// FIXME: return symbolic value for these cases.
// Example:
// FIXME: Perhaps this method should just take a 'const MemRegion*' argument
// instead of 'Loc', and have the other Loc cases handled at a higher level.
- const TypedRegion* R = cast<TypedRegion>(MR);
+ const TypedRegion *R = cast<TypedRegion>(MR);
assert(R && "bad region");
// FIXME: We should eventually handle funny addressing. e.g.:
QualType RTy = R->getValueType(getContext());
if (RTy->isStructureType())
- return RetrieveStruct(St, R);
+ return RetrieveStruct(state, R);
if (RTy->isArrayType())
- return RetrieveArray(St, R);
+ return RetrieveArray(state, R);
// FIXME: handle Vector types.
if (RTy->isVectorType())
return UnknownVal();
- RegionBindingsTy B = GetRegionBindings(St->getStore());
+ RegionBindingsTy B = GetRegionBindings(state->getStore());
RegionBindingsTy::data_type* V = B.lookup(R);
// Check if the region has a binding.
if (V)
return *V;
- GRStateRef state(St, StateMgr);
-
// Check if the region is in killset.
- if (state.contains<RegionKills>(R))
+ if (state->contains<RegionKills>(R))
return UnknownVal();
// Check if the region is an element region of a string literal.
if (isa<ElementRegion>(R) || isa<FieldRegion>(R)) {
const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
GRStateTrait<RegionDefaultValue>::lookup_type D =
- state.get<RegionDefaultValue>(SuperR);
+ state->get<RegionDefaultValue>(SuperR);
if (D) {
// If the default value is symbolic, we need to create a new symbol.
if (D->hasConjuredSymbol())
return UnknownVal();
}
-SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){
+SVal RegionStoreManager::RetrieveStruct(const GRState *state, const TypedRegion* R){
QualType T = R->getValueType(getContext());
assert(T->isStructureType());
llvm::ImmutableList<SVal> StructVal = getBasicVals().getEmptySValList();
+ // FIXME: We shouldn't use a std::vector. If RecordDecl doesn't have a
+ // reverse iterator, we should implement one.
std::vector<FieldDecl *> Fields(RD->field_begin(getContext()),
RD->field_end(getContext()));
Field != FieldEnd; ++Field) {
FieldRegion* FR = MRMgr.getFieldRegion(*Field, R);
QualType FTy = (*Field)->getType();
- SVal FieldValue = Retrieve(St, loc::MemRegionVal(FR), FTy);
+ SVal FieldValue = Retrieve(state, loc::MemRegionVal(FR), FTy);
StructVal = getBasicVals().consVals(FieldValue, StructVal);
}
return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals());
}
-SVal RegionStoreManager::RetrieveArray(const GRState* St, const TypedRegion* R){
+SVal RegionStoreManager::RetrieveArray(const GRState *state,
+ const TypedRegion * R) {
+
QualType T = R->getValueType(getContext());
ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
ElementRegion* ER = MRMgr.getElementRegion(CAT->getElementType(), Idx, R,
getContext());
QualType ETy = ER->getElementType();
- SVal ElementVal = Retrieve(St, loc::MemRegionVal(ER), ETy);
+ SVal ElementVal = Retrieve(state, loc::MemRegionVal(ER), ETy);
ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal);
}
return store;
}
-const GRState* RegionStoreManager::Bind(const GRState* St, Loc L, SVal V) {
+const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
// If we get here, the location should be a region.
const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
- assert(R);
// Check if the region is a struct region.
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
if (TR->getValueType(getContext())->isStructureType())
- return BindStruct(St, TR, V);
+ return BindStruct(state, TR, V);
- Store store = St->getStore();
- RegionBindingsTy B = GetRegionBindings(store);
+ RegionBindingsTy B = GetRegionBindings(state->getStore());
if (V.isUnknown()) {
- // Remove the binding.
- store = RBFactory.Remove(B, R).getRoot();
-
- // Add the region to the killset.
- GRStateRef state(St, StateMgr);
- St = state.add<RegionKills>(R);
+ B = RBFactory.Remove(B, R); // Remove the binding.
+ state = state->add<RegionKills>(R); // Add the region to the killset.
}
else
- store = RBFactory.Add(B, R, V).getRoot();
+ B = RBFactory.Add(B, R, V);
- return StateMgr.MakeStateWithStore(St, store);
+ return state->makeWithStore(B.getRoot());
}
-const GRState* RegionStoreManager::BindDecl(const GRState* St,
+const GRState *RegionStoreManager::BindDecl(const GRState *state,
const VarDecl* VD, SVal InitVal) {
QualType T = VD->getType();
VarRegion* VR = MRMgr.getVarRegion(VD);
if (T->isArrayType())
- return BindArray(St, VR, InitVal);
+ return BindArray(state, VR, InitVal);
if (T->isStructureType())
- return BindStruct(St, VR, InitVal);
+ return BindStruct(state, VR, InitVal);
- return Bind(St, Loc::MakeVal(VR), InitVal);
+ return Bind(state, Loc::MakeVal(VR), InitVal);
}
// FIXME: this method should be merged into Bind().
-const GRState*
-RegionStoreManager::BindCompoundLiteral(const GRState* St,
- const CompoundLiteralExpr* CL, SVal V) {
+const GRState *
+RegionStoreManager::BindCompoundLiteral(const GRState *state,
+ const CompoundLiteralExpr* CL,
+ SVal V) {
+
CompoundLiteralRegion* R = MRMgr.getCompoundLiteralRegion(CL);
- return Bind(St, loc::MemRegionVal(R), V);
+ return Bind(state, loc::MemRegionVal(R), V);
}
-const GRState* RegionStoreManager::BindArray(const GRState* St,
- const TypedRegion* R, SVal Init) {
+const GRState *RegionStoreManager::BindArray(const GRState *state,
+ const TypedRegion* R,
+ SVal Init) {
+
QualType T = R->getValueType(getContext());
assert(T->isArrayType());
// When we are binding the whole array, it always has default value 0.
- GRStateRef state(St, StateMgr);
- St = state.set<RegionDefaultValue>(R, NonLoc::MakeIntVal(getBasicVals(), 0,
- false));
+ state = state->set<RegionDefaultValue>(R, NonLoc::MakeIntVal(getBasicVals(),
+ 0, false));
ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
Idx, R, getContext());
SVal V = NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true);
- St = Bind(St, loc::MemRegionVal(ER), V);
+ state = Bind(state, loc::MemRegionVal(ER), V);
}
- return St;
+ return state;
}
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
Idx, R, getContext());
if (CAT->getElementType()->isStructureType())
- St = BindStruct(St, ER, *VI);
+ state = BindStruct(state, ER, *VI);
else
- St = Bind(St, Loc::MakeVal(ER), *VI);
+ state = Bind(state, Loc::MakeVal(ER), *VI);
}
- return St;
+ return state;
}
-const GRState*
-RegionStoreManager::BindStruct(const GRState* St, const TypedRegion* R, SVal V){
+const GRState *
+RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R,
+ SVal V) {
+
+ if (!Features.supportsFields())
+ return state;
+
QualType T = R->getValueType(getContext());
assert(T->isStructureType());
RecordDecl* RD = RT->getDecl();
if (!RD->isDefinition())
- return St;
+ return state;
- if (V.isUnknown())
- return KillStruct(St, R);
-
- // We may get non-CompoundVal accidentally due to imprecise cast logic. Ignore
- // them and make struct unknown.
- if (!isa<nonloc::CompoundVal>(V))
- return KillStruct(St, R);
+ // We may get non-CompoundVal accidentally due to imprecise cast logic.
+ // Ignore them and kill the field values.
+ if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
+ return KillStruct(state, R);
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
- RecordDecl::field_iterator FI = RD->field_begin(getContext()),
- FE = RD->field_end(getContext());
-
- for (; FI != FE; ++FI, ++VI) {
+
+ for (RecordDecl::field_iterator FI = RD->field_begin(getContext()),
+ FE = RD->field_end(getContext());
+ FI != FE; ++FI, ++VI) {
// There may be fewer values than fields only when we are initializing a
// struct decl. In this case, mark the region as having default value.
if (VI == VE) {
- GRStateRef state(St, StateMgr);
const NonLoc& Idx = NonLoc::MakeIntVal(getBasicVals(), 0, false);
- St = state.set<RegionDefaultValue>(R, Idx);
+ state = state->set<RegionDefaultValue>(R, Idx);
break;
}
FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
if (Loc::IsLocType(FTy) || FTy->isIntegerType())
- St = Bind(St, Loc::MakeVal(FR), *VI);
-
+ state = Bind(state, Loc::MakeVal(FR), *VI);
else if (FTy->isArrayType())
- St = BindArray(St, FR, *VI);
-
+ state = BindArray(state, FR, *VI);
else if (FTy->isStructureType())
- St = BindStruct(St, FR, *VI);
+ state = BindStruct(state, FR, *VI);
}
- return St;
+ return state;
}
-const GRState* RegionStoreManager::KillStruct(const GRState* St,
+const GRState *RegionStoreManager::KillStruct(const GRState *state,
const TypedRegion* R){
- GRStateRef state(St, StateMgr);
- // Kill the struct region because it is assigned "unknown".
- St = state.add<RegionKills>(R);
-
- // Set the default value of the struct region to "unknown".
- St = state.set<RegionDefaultValue>(R, UnknownVal());
-
- Store store = St->getStore();
+ // (1) Kill the struct region because it is assigned "unknown".
+ // (2) Set the default value of the struct region to "unknown".
+ state = state->add<RegionKills>(R)->set<RegionDefaultValue>(R, UnknownVal());
+ Store store = state->getStore();
RegionBindingsTy B = GetRegionBindings(store);
// Remove all bindings for the subregions of the struct.
for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
- const MemRegion* r = I.getKey();
- if (const SubRegion* sr = dyn_cast<SubRegion>(r))
- if (sr->isSubRegionOf(R))
- store = Remove(store, Loc::MakeVal(sr));
+ const MemRegion* R = I.getKey();
+ if (const SubRegion* subRegion = dyn_cast<SubRegion>(R))
+ if (subRegion->isSubRegionOf(R))
+ store = Remove(store, Loc::MakeVal(subRegion));
// FIXME: Maybe we should also remove the bindings for the "views" of the
// subregions.
}
- return StateMgr.MakeStateWithStore(St, store);
+ return state->makeWithStore(store);
}
//===----------------------------------------------------------------------===//
// Region views.
//===----------------------------------------------------------------------===//
-const GRState* RegionStoreManager::AddRegionView(const GRState* St,
- const MemRegion* View,
- const MemRegion* Base) {
- GRStateRef state(St, StateMgr);
+const GRState *RegionStoreManager::AddRegionView(const GRState *state,
+ const MemRegion* View,
+ const MemRegion* Base) {
// First, retrieve the region view of the base region.
- const RegionViews* d = state.get<RegionViewMap>(Base);
+ const RegionViews* d = state->get<RegionViewMap>(Base);
RegionViews L = d ? *d : RVFactory.GetEmptySet();
// Now add View to the region view.
L = RVFactory.Add(L, View);
// Create a new state with the new region view.
- return state.set<RegionViewMap>(Base, L);
+ return state->set<RegionViewMap>(Base, L);
}
-const GRState* RegionStoreManager::RemoveRegionView(const GRState* St,
- const MemRegion* View,
- const MemRegion* Base) {
- GRStateRef state(St, StateMgr);
-
+const GRState *RegionStoreManager::RemoveRegionView(const GRState *state,
+ const MemRegion* View,
+ const MemRegion* Base) {
// Retrieve the region view of the base region.
- const RegionViews* d = state.get<RegionViewMap>(Base);
+ const RegionViews* d = state->get<RegionViewMap>(Base);
// If the base region has no view, return.
if (!d)
- return St;
+ return state;
// Remove the view.
- RegionViews V = *d;
- V = RVFactory.Remove(V, View);
-
- return state.set<RegionViewMap>(Base, V);
+ return state->set<RegionViewMap>(Base, RVFactory.Remove(*d, View));
}
-const GRState* RegionStoreManager::setCastType(const GRState* St,
- const MemRegion* R, QualType T) {
- GRStateRef state(St, StateMgr);
- return state.set<RegionCasts>(R, T);
+const GRState *RegionStoreManager::setCastType(const GRState *state, const MemRegion* R,
+ QualType T) {
+ return state->set<RegionCasts>(R, T);
}
-const GRState* RegionStoreManager::setDefaultValue(const GRState* St,
- const MemRegion* R, SVal V) {
- GRStateRef state(St, StateMgr);
- return state.set<RegionDefaultValue>(R, V);
+const GRState *RegionStoreManager::setDefaultValue(const GRState *state,
+ const MemRegion* R, SVal V) {
+ return state->set<RegionDefaultValue>(R, V);
}
//===----------------------------------------------------------------------===//
SymReaper.markLive(*SI);
}
-Store RegionStoreManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
+Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
-{
-
+{
Store store = state->getStore();
RegionBindingsTy B = GetRegionBindings(store);
// Do a pass over the regions in the store. For VarRegions we check if
// the variable is still live and if so add it to the list of live roots.
- // For other regions we populate our region backmap.
-
+ // For other regions we populate our region backmap.
llvm::SmallVector<const MemRegion*, 10> IntermediateRoots;
for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {