[cfe-commits] r61274 - in /cfe/trunk: include/clang/Analysis/PathSensitive/ lib/Analysis/ test/Analysis/
Zhongxing Xu
xuzhongxing at gmail.com
Fri Dec 19 22:32:15 PST 2008
Author: zhongxingxu
Date: Sat Dec 20 00:32:12 2008
New Revision: 61274
URL: http://llvm.org/viewvc/llvm-project?rev=61274&view=rev
Log:
Lazy bingding for region-store manager.
* Now Bind() methods take and return GRState* because binding could
also alter GDM.
* No variables are initialized except those declared with initial
values.
* failed C test cases are due to bugs in RemoveDeadBindings(),
which removes constraints that is still alive. This will be fixed in later
patch.
* default value of array and struct regions will be implemented in later patch.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
cfe/trunk/lib/Analysis/BasicStore.cpp
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/lib/Analysis/GRState.cpp
cfe/trunk/lib/Analysis/MemRegion.cpp
cfe/trunk/lib/Analysis/RegionStore.cpp
cfe/trunk/lib/Analysis/SVals.cpp
cfe/trunk/lib/Analysis/SymbolManager.cpp
cfe/trunk/test/Analysis/null-deref-ps.c
cfe/trunk/test/Analysis/uninit-vals-ps-region.c
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Sat Dec 20 00:32:12 2008
@@ -336,15 +336,24 @@
typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
- const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal* IVal,
- unsigned Count);
+ const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal IVal) {
+ // Store manager should return a persistent state.
+ return StoreMgr->BindDecl(St, VD, IVal);
+ }
+
+ const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
+ // Store manager should return a persistent state.
+ return StoreMgr->BindDeclWithNoInit(St, VD);
+ }
/// BindCompoundLiteral - Return the state that has the bindings currently
/// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
- const GRState* BindCompoundLiteral(const GRState* state,
- const CompoundLiteralExpr* CL, SVal V);
+ const GRState* BindCompoundLiteral(const GRState* St,
+ const CompoundLiteralExpr* CL, SVal V) {
+ return StoreMgr->BindCompoundLiteral(St, CL, V);
+ }
const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
const LiveVariables& Liveness,
@@ -468,11 +477,9 @@
return StoreMgr->GetRegionSVal(state, R);
}
- void BindLoc(GRState& St, Loc LV, SVal V) {
- St.St = StoreMgr->Bind(St.St, LV, V);
+ const GRState* BindLoc(const GRState* St, Loc LV, SVal V) {
+ return StoreMgr->Bind(St, LV, V);
}
-
- const GRState* BindLoc(const GRState* St, Loc LV, SVal V);
void Unbind(GRState& St, Loc LV) {
St.St = StoreMgr->Remove(St.St, LV);
@@ -481,6 +488,9 @@
const GRState* Unbind(const GRState* St, Loc LV);
const GRState* getPersistentState(GRState& Impl);
+
+ // MakeStateWithStore - get a persistent state with the new store.
+ const GRState* MakeStateWithStore(const GRState* St, Store store);
bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V);
bool isEqual(const GRState* state, Expr* Ex, uint64_t);
@@ -501,7 +511,15 @@
return addGDM(st, GRStateTrait<T>::GDMIndex(),
GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
}
-
+
+ template <typename T>
+ const GRState* add(const GRState* st,
+ typename GRStateTrait<T>::key_type K,
+ typename GRStateTrait<T>::context_type C) {
+ return addGDM(st, GRStateTrait<T>::GDMIndex(),
+ GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C)));
+ }
+
template <typename T>
const GRState* remove(const GRState* st,
typename GRStateTrait<T>::key_type K,
@@ -587,14 +605,12 @@
return GRStateRef(Mgr->BindExpr(St, Ex, V, Invalidate), *Mgr);
}
- GRStateRef BindDecl(const VarDecl* VD, SVal* InitVal, unsigned Count) {
- return GRStateRef(Mgr->BindDecl(St, VD, InitVal, Count), *Mgr);
+ GRStateRef BindDecl(const VarDecl* VD, SVal InitVal) {
+ return GRStateRef(Mgr->BindDecl(St, VD, InitVal), *Mgr);
}
GRStateRef BindLoc(Loc LV, SVal V) {
- GRState StImpl = *St;
- Mgr->BindLoc(StImpl, LV, V);
- return GRStateRef(Mgr->getPersistentState(StImpl), *Mgr);
+ return GRStateRef(Mgr->BindLoc(St, LV, V), *Mgr);
}
GRStateRef BindLoc(SVal LV, SVal V) {
@@ -644,7 +660,12 @@
typename GRStateTrait<T>::value_type E) {
return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr);
}
-
+
+ template<typename T>
+ GRStateRef add(typename GRStateTrait<T>::key_type K) {
+ return GRStateRef(Mgr->add<T>(St, K, get_context<T>()), *Mgr);
+ }
+
template<typename T>
GRStateRef remove(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::context_type C) {
@@ -658,7 +679,7 @@
template<typename T>
bool contains(typename GRStateTrait<T>::key_type key) const {
- return St->contains(key);
+ return St->contains<T>(key);
}
// Lvalue methods.
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Sat Dec 20 00:32:12 2008
@@ -99,7 +99,7 @@
const MemRegion* getSuperRegion() const {
return superRegion;
}
-
+
static bool classof(const MemRegion* R) {
return R->getKind() > SymbolicRegionKind;
}
@@ -466,6 +466,12 @@
assert(R);
return R == globals;
}
+
+ /// onStack - check if the region is allocated on the stack.
+ bool onStack(const MemRegion* R);
+
+ /// onHeap - check if the region is allocated on the heap, usually by malloc.
+ bool onHeap(const MemRegion* R);
/// getAllocaRegion - Retrieve a region associated with a call to alloca().
AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt);
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Sat Dec 20 00:32:12 2008
@@ -71,7 +71,13 @@
inline bool operator!=(const SVal& R) const {
return !(*this == R);
}
-
+
+ /// MakeSymbolValue - make a unique symbol value for the region R according to
+ /// its kind. R should be a scalar region. The symbol value T has the same
+ /// type as R's rvalue type.
+ static SVal MakeSymbolValue(SymbolManager& SymMgr, const MemRegion* R,
+ QualType T);
+
static SVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R,
const llvm::APSInt* Idx, QualType T);
@@ -171,6 +177,8 @@
// Utility methods to create NonLocs.
+ static NonLoc MakeVal(SymbolRef sym);
+
static NonLoc MakeVal(BasicValueFactory& BasicVals, unsigned X,
bool isUnsigned);
@@ -212,6 +220,8 @@
static Loc MakeVal(const MemRegion* R);
static Loc MakeVal(AddrLabelExpr* E);
+
+ static Loc MakeVal(SymbolRef sym);
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Sat Dec 20 00:32:12 2008
@@ -49,16 +49,19 @@
SVal GetRegionSVal(const GRState* state, const MemRegion* R) {
return Retrieve(state, loc::MemRegionVal(R));
}
-
- virtual Store Bind(Store St, Loc LV, SVal V) = 0;
- virtual Store Remove(Store St, Loc LV) = 0;
+
+ /// Bind value V to location L.
+ virtual const GRState* Bind(const GRState* St, Loc L, SVal V) = 0;
+
+ virtual Store Remove(Store St, Loc L) = 0;
/// BindCompoundLiteral - Return the store that has the bindings currently
/// 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 Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL,
- SVal V) = 0;
+ virtual const GRState* BindCompoundLiteral(const GRState* St,
+ const CompoundLiteralExpr* CL,
+ SVal V) = 0;
virtual Store getInitialStore() = 0;
virtual MemRegionManager& getRegionManager() = 0;
@@ -112,8 +115,11 @@
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) = 0;
- virtual Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal,
- unsigned Count) = 0;
+ virtual const GRState* BindDecl(const GRState* St, const VarDecl* VD,
+ SVal InitVal) = 0;
+
+ virtual const GRState* BindDeclWithNoInit(const GRState* St,
+ const VarDecl* VD) = 0;
virtual const GRState* setExtent(const GRState* St,
const MemRegion* R, SVal Extent) {
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h Sat Dec 20 00:32:12 2008
@@ -104,15 +104,15 @@
};
class SymbolDataParmVar : public SymbolData {
- ParmVarDecl *VD;
+ const ParmVarDecl *VD;
public:
- SymbolDataParmVar(SymbolRef MySym, ParmVarDecl* vd)
+ SymbolDataParmVar(SymbolRef MySym, const ParmVarDecl* vd)
: SymbolData(ParmKind, MySym), VD(vd) {}
- ParmVarDecl* getDecl() const { return VD; }
+ const ParmVarDecl* getDecl() const { return VD; }
- static void Profile(llvm::FoldingSetNodeID& profile, ParmVarDecl* VD) {
+ static void Profile(llvm::FoldingSetNodeID& profile, const ParmVarDecl* VD) {
profile.AddInteger((unsigned) ParmKind);
profile.AddPointer(VD);
}
@@ -128,15 +128,15 @@
};
class SymbolDataGlobalVar : public SymbolData {
- VarDecl *VD;
+ const VarDecl *VD;
public:
- SymbolDataGlobalVar(SymbolRef MySym, VarDecl* vd) :
+ SymbolDataGlobalVar(SymbolRef MySym, const VarDecl* vd) :
SymbolData(GlobalKind, MySym), VD(vd) {}
- VarDecl* getDecl() const { return VD; }
+ const VarDecl* getDecl() const { return VD; }
- static void Profile(llvm::FoldingSetNodeID& profile, VarDecl* VD) {
+ static void Profile(llvm::FoldingSetNodeID& profile, const VarDecl* VD) {
profile.AddInteger((unsigned) GlobalKind);
profile.AddPointer(VD);
}
@@ -275,8 +275,10 @@
: SymbolCounter(0), BPAlloc(bpalloc) {}
~SymbolManager();
-
- SymbolRef getSymbol(VarDecl* D);
+
+ /// Make a unique symbol for MemRegion R according to its kind.
+ SymbolRef getSymbol(const MemRegion* R);
+ SymbolRef getSymbol(const VarDecl* D);
SymbolRef getElementSymbol(const MemRegion* R, const llvm::APSInt* Idx);
SymbolRef getFieldSymbol(const MemRegion* R, const FieldDecl* D);
SymbolRef getConjuredSymbol(Stmt* E, QualType T, unsigned VisitCount);
Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Sat Dec 20 00:32:12 2008
@@ -39,7 +39,14 @@
~BasicStoreManager() {}
SVal Retrieve(const GRState *state, Loc LV, QualType T);
- Store Bind(Store St, Loc LV, SVal V);
+
+ const GRState* Bind(const GRState* St, Loc L, SVal V) {
+ Store store = St->getStore();
+ store = BindInternal(store, L, V);
+ return StateMgr.MakeStateWithStore(St, store);
+ }
+
+ Store BindInternal(Store St, Loc LV, SVal V);
Store Remove(Store St, Loc LV);
Store getInitialStore();
MemRegionManager& getRegionManager() { return MRMgr; }
@@ -49,9 +56,10 @@
return loc::MemRegionVal(MRMgr.getVarRegion(VD));
}
- Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL,
- SVal V) {
- return store;
+ const GRState* BindCompoundLiteral(const GRState* St,
+ const CompoundLiteralExpr* CL,
+ SVal V) {
+ return St;
}
SVal getLValueVar(const GRState* St, const VarDecl* VD);
@@ -89,7 +97,25 @@
void iterBindings(Store store, BindingsHandler& f);
- Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal, unsigned Count);
+ const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal) {
+ Store store = St->getStore();
+ store = BindDeclInternal(store, VD, &InitVal);
+ return StateMgr.MakeStateWithStore(St, store);
+ }
+
+ const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
+ Store store = St->getStore();
+ store = BindDeclInternal(store, VD, 0);
+ return StateMgr.MakeStateWithStore(St, store);
+ }
+
+ const GRState* BindDecl(const GRState* St, const VarDecl* VD) {
+ Store store = St->getStore();
+ store = BindDeclInternal(store, VD, 0);
+ return StateMgr.MakeStateWithStore(St, store);
+ }
+
+ Store BindDeclInternal(Store store, const VarDecl* VD, SVal* InitVal);
static inline VarBindingsTy GetVarBindings(Store store) {
return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
@@ -286,7 +312,7 @@
return UnknownVal();
}
-Store BasicStoreManager::Bind(Store store, Loc LV, SVal V) {
+Store BasicStoreManager::BindInternal(Store store, Loc LV, SVal V) {
switch (LV.getSubKind()) {
case loc::MemRegionKind: {
const VarRegion* R =
@@ -421,8 +447,8 @@
SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
MRMgr.getHeapRegion());
- St = Bind(St, loc::MemRegionVal(MRMgr.getVarRegion(PD)),
- loc::MemRegionVal(SelfRegion));
+ St = BindInternal(St, loc::MemRegionVal(MRMgr.getVarRegion(PD)),
+ loc::MemRegionVal(SelfRegion));
}
}
}
@@ -441,15 +467,15 @@
? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
: UndefinedVal();
- St = Bind(St, loc::MemRegionVal(MRMgr.getVarRegion(VD)), X);
+ St = BindInternal(St, loc::MemRegionVal(MRMgr.getVarRegion(VD)), X);
}
}
}
return St;
}
-Store BasicStoreManager::BindDecl(Store store, const VarDecl* VD,
- SVal* InitVal, unsigned Count) {
+Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
+ SVal* InitVal) {
BasicValueFactory& BasicVals = StateMgr.getBasicVals();
@@ -479,16 +505,16 @@
if (!InitVal) {
QualType T = VD->getType();
if (Loc::IsLocType(T))
- store = Bind(store, getLoc(VD),
+ store = BindInternal(store, getLoc(VD),
loc::ConcreteInt(BasicVals.getValue(0, T)));
else if (T->isIntegerType())
- store = Bind(store, getLoc(VD),
+ store = BindInternal(store, getLoc(VD),
nonloc::ConcreteInt(BasicVals.getValue(0, T)));
else {
// assert(0 && "ignore other types of variables");
}
} else {
- store = Bind(store, getLoc(VD), *InitVal);
+ store = BindInternal(store, getLoc(VD), *InitVal);
}
}
} else {
@@ -496,7 +522,7 @@
QualType T = VD->getType();
if (Loc::IsLocType(T) || T->isIntegerType()) {
SVal V = InitVal ? *InitVal : UndefinedVal();
- store = Bind(store, getLoc(VD), V);
+ store = BindInternal(store, getLoc(VD), V);
}
}
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Sat Dec 20 00:32:12 2008
@@ -1811,7 +1811,8 @@
for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
const GRState* St = GetState(*I);
unsigned Count = Builder->getCurrentBlockCount();
-
+
+ // Decls without InitExpr are not initialized explicitly.
if (InitEx) {
SVal InitVal = GetSVal(St, InitEx);
QualType T = VD->getType();
@@ -1829,11 +1830,9 @@
}
}
- St = StateMgr.BindDecl(St, VD, &InitVal, Count);
- }
- else
- St = StateMgr.BindDecl(St, VD, 0, Count);
-
+ St = StateMgr.BindDecl(St, VD, InitVal);
+ } else
+ St = StateMgr.BindDeclWithNoInit(St, VD);
// Check if 'VD' is a VLA and if so check if has a non-zero size.
QualType T = getContext().getCanonicalType(VD->getType());
Modified: cfe/trunk/lib/Analysis/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRState.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRState.cpp (original)
+++ cfe/trunk/lib/Analysis/GRState.cpp Sat Dec 20 00:32:12 2008
@@ -59,51 +59,6 @@
LSymbols, DSymbols);
}
-const GRState* GRStateManager::BindLoc(const GRState* St, Loc LV, SVal V) {
-
- Store OldStore = St->getStore();
- Store NewStore = StoreMgr->Bind(OldStore, LV, V);
-
- if (NewStore == OldStore)
- return St;
-
- GRState NewSt = *St;
- NewSt.St = NewStore;
- return getPersistentState(NewSt);
-}
-
-const GRState* GRStateManager::BindDecl(const GRState* St, const VarDecl* VD,
- SVal* InitVal, unsigned Count) {
- Store OldStore = St->getStore();
- Store NewStore = StoreMgr->BindDecl(OldStore, VD, InitVal, Count);
-
- if (NewStore == OldStore)
- return St;
-
- GRState NewSt = *St;
- NewSt.St = NewStore;
- return getPersistentState(NewSt);
-}
-
-/// BindCompoundLiteral - Return the store that has the bindings currently
-/// 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.
-const GRState*
-GRStateManager::BindCompoundLiteral(const GRState* state,
- const CompoundLiteralExpr* CL, SVal ILV) {
-
- Store oldStore = state->getStore();
- Store newStore = StoreMgr->BindCompoundLiteral(oldStore, CL, ILV);
-
- if (newStore == oldStore)
- return state;
-
- GRState newState = *state;
- newState.St = newStore;
- return getPersistentState(newState);
-}
-
const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) {
Store OldStore = St->getStore();
Store NewStore = StoreMgr->Remove(OldStore, LV);
@@ -140,6 +95,13 @@
return I;
}
+const GRState* GRStateManager::MakeStateWithStore(const GRState* St,
+ Store store) {
+ GRState NewSt = *St;
+ NewSt.St = store;
+ return getPersistentState(NewSt);
+}
+
//===----------------------------------------------------------------------===//
// State pretty-printing.
Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Sat Dec 20 00:32:12 2008
@@ -215,6 +215,20 @@
return LazyAllocate(unknown);
}
+bool MemRegionManager::onStack(const MemRegion* R) {
+ while (const SubRegion* SR = dyn_cast<SubRegion>(R))
+ R = SR->getSuperRegion();
+
+ return (R != 0) && (R == stack);
+}
+
+bool MemRegionManager::onHeap(const MemRegion* R) {
+ while (const SubRegion* SR = dyn_cast<SubRegion>(R))
+ R = SR->getSuperRegion();
+
+ return (R != 0) && (R == heap);
+}
+
StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
llvm::FoldingSetNodeID ID;
MemSpaceRegion* GlobalsR = getGlobalsRegion();
Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Sat Dec 20 00:32:12 2008
@@ -62,6 +62,16 @@
};
}
+// Regions that have default value zero.
+// FIXME: redefinition!
+// typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionDefaultValue;
+// static int RegionDefaultValueIndex = 0;
+// namespace clang {
+// template<> struct GRStateTrait<RegionDefaultValue>
+// : public GRStatePartialTrait<RegionDefaultValue> {
+// static void* GDMIndex() { return &RegionDefaultValueIndex; }
+// };
+// }
namespace {
@@ -83,7 +93,8 @@
MemRegionManager& getRegionManager() { return MRMgr; }
- Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, SVal V);
+ const GRState* BindCompoundLiteral(const GRState* St,
+ const CompoundLiteralExpr* CL, SVal V);
SVal getLValueString(const GRState* St, const StringLiteral* S);
@@ -107,13 +118,24 @@
CastResult CastRegion(const GRState* state, const MemRegion* R,
QualType CastToTy);
+ /// 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());
- Store Bind(Store St, Loc LV, SVal V);
+ const GRState* Bind(const GRState* St, Loc LV, SVal V);
Store Remove(Store store, Loc LV);
- Store getInitialStore();
+ Store getInitialStore() { return RBFactory.GetEmptyMap().getRoot(); }
/// getSelfRegion - Returns the region for the 'self' (Objective-C) or
/// 'this' object (C++). When used when analyzing a normal function this
@@ -133,7 +155,11 @@
void UpdateLiveSymbols(SVal X, LiveSymbolsTy& LSymbols);
- Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal, unsigned Count);
+ const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal);
+
+ const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
+ return St;
+ }
const GRState* setExtent(const GRState* St, const MemRegion* R, SVal Extent);
@@ -152,22 +178,16 @@
return loc::MemRegionVal(MRMgr.getVarRegion(VD));
}
- Store InitializeArray(Store store, const TypedRegion* R, SVal Init);
- Store BindArrayToVal(Store store, const TypedRegion* BaseR, SVal V);
- Store BindArrayToSymVal(Store store, const TypedRegion* BaseR);
-
- Store InitializeStruct(Store store, const TypedRegion* R, SVal Init);
- Store BindStructToVal(Store store, const TypedRegion* BaseR, SVal V);
- Store BindStructToSymVal(Store store, const TypedRegion* BaseR);
+ const GRState* BindArray(const GRState* St, const TypedRegion* R, SVal V);
/// 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(Store store, const TypedRegion* R);
+ SVal RetrieveStruct(const GRState* St, const TypedRegion* R);
- Store BindStruct(Store store, const TypedRegion* R, SVal V);
+ const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V);
// Utility methods.
BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
@@ -396,41 +416,60 @@
return CastResult(AddRegionView(state, ViewR, R), ViewR);
}
-SVal RegionStoreManager::Retrieve(const GRState* state, Loc L, QualType T) {
+SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined");
- Store S = state->getStore();
-
- switch (L.getSubKind()) {
- case loc::MemRegionKind: {
- const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
- assert(R && "bad region");
-
- if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
- if (TR->getRValueType(getContext())->isStructureType())
- return RetrieveStruct(S, TR);
-
- RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(S));
- RegionBindingsTy::data_type* V = B.lookup(R);
- return V ? *V : UnknownVal();
- }
- case loc::SymbolValKind:
+ if (isa<loc::SymbolVal>(L))
return UnknownVal();
- case loc::ConcreteIntKind:
- return UndefinedVal(); // As in BasicStoreManager.
+ if (isa<loc::ConcreteInt>(L))
+ return UndefinedVal();
- case loc::FuncValKind:
+ if (isa<loc::FuncVal>(L))
return L;
- default:
- assert(false && "Invalid Location");
- return L;
- }
+ const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
+ assert(R && "bad region");
+
+ if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
+ if (TR->getRValueType(getContext())->isStructureType())
+ return RetrieveStruct(St, TR);
+
+ RegionBindingsTy B = GetRegionBindings(St->getStore());
+ RegionBindingsTy::data_type* V = B.lookup(R);
+
+ // Check if the region has a binding.
+ if (V)
+ return *V;
+
+ // Check if the region is in killset.
+ GRStateRef state(St, StateMgr);
+ if (state.contains<RegionKills>(R))
+ return UnknownVal();
+
+ // The location is not initialized.
+
+ // We treat parameters as symbolic values.
+ if (const VarRegion* VR = dyn_cast<VarRegion>(R))
+ if (isa<ParmVarDecl>(VR->getDecl()))
+ return SVal::MakeSymbolValue(getSymbolManager(), VR,
+ VR->getRValueType(getContext()));
+
+ if (MRMgr.onStack(R) || MRMgr.onHeap(R))
+ return UndefinedVal();
+ else
+ return SVal::MakeSymbolValue(getSymbolManager(), R,
+ cast<TypedRegion>(R)->getRValueType(getContext()));
+
+ // FIXME: consider default values for elements and fields.
}
-SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
+SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){
+
+ Store store = St->getStore();
+ GRStateRef state(St, StateMgr);
+
// FIXME: Verify we want getRValueType instead of getLValueType.
QualType T = R->getRValueType(getContext());
assert(T->isStructureType());
@@ -447,10 +486,21 @@
FieldEnd = Fields.rend();
Field != FieldEnd; ++Field) {
FieldRegion* FR = MRMgr.getFieldRegion(*Field, R);
- RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(store));
+ RegionBindingsTy B = GetRegionBindings(store);
RegionBindingsTy::data_type* data = B.lookup(FR);
- SVal FieldValue = data ? *data : UnknownVal();
+ SVal FieldValue;
+ if (data)
+ FieldValue = *data;
+ else if (state.contains<RegionKills>(FR))
+ FieldValue = UnknownVal();
+ else {
+ if (MRMgr.onStack(FR) || MRMgr.onHeap(FR))
+ FieldValue = UndefinedVal();
+ else
+ FieldValue = SVal::MakeSymbolValue(getSymbolManager(), FR,
+ FR->getRValueType(getContext()));
+ }
StructVal = getBasicVals().consVals(FieldValue, StructVal);
}
@@ -458,25 +508,37 @@
return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals());
}
-Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) {
- if (LV.getSubKind() == loc::SymbolValKind)
- return store;
+const GRState* RegionStoreManager::Bind(const GRState* St, Loc L, SVal V) {
+ // Currently we don't bind value to symbolic location. But if the logic is
+ // made clear, we might change this decision.
+ if (isa<loc::SymbolVal>(L))
+ return St;
- assert(LV.getSubKind() == loc::MemRegionKind);
-
- const MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
-
+ // 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))
// FIXME: Verify we want getRValueType().
if (TR->getRValueType(getContext())->isStructureType())
- return BindStruct(store, TR, V);
+ return BindStruct(St, TR, V);
+ Store store = St->getStore();
RegionBindingsTy B = GetRegionBindings(store);
- return V.isUnknown()
- ? RBFactory.Remove(B, R).getRoot()
- : RBFactory.Add(B, R, V).getRoot();
+
+ 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);
+ }
+ else
+ store = RBFactory.Add(B, R, V).getRoot();
+
+ return StateMgr.MakeStateWithStore(St, store);
}
Store RegionStoreManager::Remove(Store store, Loc L) {
@@ -488,150 +550,37 @@
return RBFactory.Remove(B, R).getRoot();
}
-Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, SVal V){
- // Verify we want getRValueType.
- QualType T = R->getRValueType(getContext());
- assert(T->isStructureType());
-
- const RecordType* RT = cast<RecordType>(T.getTypePtr());
- RecordDecl* RD = RT->getDecl();
-
- if (!RD->isDefinition()) {
- // This can only occur when a pointer of incomplete struct type is used as a
- // function argument.
- assert(V.isUnknown());
- return store;
- }
-
- RegionBindingsTy B = GetRegionBindings(store);
-
- if (isa<UnknownVal>(V))
- return BindStructToVal(store, R, UnknownVal());
-
- nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
-
- nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
- RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
-
- for (; FI != FE; ++FI, ++VI) {
- assert(VI != VE);
-
- FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
-
- B = RBFactory.Add(B, FR, *VI);
- }
-
- return B.getRoot();
-}
-
-Store RegionStoreManager::getInitialStore() {
- typedef LiveVariables::AnalysisDataTy LVDataTy;
- LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
+const GRState* RegionStoreManager::BindDecl(const GRState* St,
+ const VarDecl* VD, SVal InitVal) {
+ // All static variables are treated as symbolic values.
+ if (VD->hasGlobalStorage())
+ return St;
- Store St = RBFactory.GetEmptyMap().getRoot();
+ // Process local variables.
- for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
- NamedDecl* ND = const_cast<NamedDecl*>(I->first);
-
- if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
- // Punt on static variables for now.
- if (VD->getStorageClass() == VarDecl::Static)
- continue;
-
- VarRegion* VR = MRMgr.getVarRegion(VD);
-
- QualType T = VD->getType();
- // Only handle pointers and integers for now.
- if (Loc::IsLocType(T) || T->isIntegerType()) {
- // Initialize globals and parameters to symbolic values.
- // Initialize local variables to undefined.
- SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
- isa<ImplicitParamDecl>(VD))
- ? SVal::GetSymbolValue(getSymbolManager(), VD)
- : UndefinedVal();
-
- St = Bind(St, getVarLoc(VD), X);
- }
- else if (T->isArrayType()) {
- if (VD->hasGlobalStorage()) // Params cannot have array type.
- St = BindArrayToSymVal(St, VR);
- else
- St = BindArrayToVal(St, VR, UndefinedVal());
- }
- else if (T->isStructureType()) {
- if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
- isa<ImplicitParamDecl>(VD))
- St = BindStructToSymVal(St, VR);
- else
- St = BindStructToVal(St, VR, UndefinedVal());
- }
- }
- }
- return St;
-}
-
-Store RegionStoreManager::BindDecl(Store store, const VarDecl* VD,
- SVal* InitVal, unsigned Count) {
+ QualType T = VD->getType();
- if (VD->hasGlobalStorage()) {
- // Static global variables should not be visited here.
- assert(!(VD->getStorageClass() == VarDecl::Static &&
- VD->isFileVarDecl()));
- // Process static variables.
- if (VD->getStorageClass() == VarDecl::Static) {
- if (!InitVal) {
- // Only handle pointer and integer static variables.
-
- QualType T = VD->getType();
-
- if (Loc::IsLocType(T))
- store = Bind(store, getVarLoc(VD),
- loc::ConcreteInt(getBasicVals().getValue(0, T)));
-
- else if (T->isIntegerType())
- store = Bind(store, getVarLoc(VD),
- loc::ConcreteInt(getBasicVals().getValue(0, T)));
-
- // Other types of static local variables are not handled yet.
- } else {
- store = Bind(store, getVarLoc(VD), *InitVal);
- }
- }
- } else {
- // Process local variables.
-
- QualType T = VD->getType();
+ VarRegion* VR = MRMgr.getVarRegion(VD);
+
+ if (Loc::IsLocType(T) || T->isIntegerType())
+ return Bind(St, Loc::MakeVal(VR), InitVal);
- VarRegion* VR = MRMgr.getVarRegion(VD);
+ else if (T->isArrayType())
+ return BindArray(St, VR, InitVal);
- if (Loc::IsLocType(T) || T->isIntegerType()) {
- SVal V = InitVal ? *InitVal : UndefinedVal();
- store = Bind(store, loc::MemRegionVal(VR), V);
- }
- else if (T->isArrayType()) {
- if (!InitVal)
- store = BindArrayToVal(store, VR, UndefinedVal());
- else
- store = InitializeArray(store, VR, *InitVal);
- }
- else if (T->isStructureType()) {
- if (!InitVal)
- store = BindStructToVal(store, VR, UndefinedVal());
- else
- store = InitializeStruct(store, VR, *InitVal);
- }
+ else if (T->isStructureType())
+ return BindStruct(St, VR, InitVal);
- // Other types of local variables are not handled yet.
- }
- return store;
+ // Other types of variable are not supported yet.
+ return St;
}
-Store RegionStoreManager::BindCompoundLiteral(Store store,
- const CompoundLiteralExpr* CL,
- SVal V) {
+// FIXME: this method should be merged into Bind().
+const GRState*
+RegionStoreManager::BindCompoundLiteral(const GRState* St,
+ const CompoundLiteralExpr* CL, SVal V) {
CompoundLiteralRegion* R = MRMgr.getCompoundLiteralRegion(CL);
- store = Bind(store, loc::MemRegionVal(R), V);
- return store;
+ return Bind(St, loc::MemRegionVal(R), V);
}
const GRState* RegionStoreManager::setExtent(const GRState* St,
@@ -781,19 +730,24 @@
}
}
-Store RegionStoreManager::InitializeArray(Store store, const TypedRegion* R,
- SVal Init) {
+const GRState* RegionStoreManager::BindArray(const GRState* St,
+ const TypedRegion* R, SVal Init) {
// FIXME: Verify we should use getLValueType or getRValueType.
QualType T = R->getRValueType(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::MakeVal(getBasicVals(), 0,
+ // false));
+
+ Store store = St->getStore();
+
ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
llvm::APSInt Size(CAT->getSize(), false);
-
- llvm::APSInt i = getBasicVals().getValue(0, Size.getBitWidth(),
- Size.isUnsigned());
+ llvm::APSInt i = getBasicVals().getZeroWithPtrWidth(false);
// Check if the init expr is a StringLiteral.
if (isa<loc::MemRegionVal>(Init)) {
@@ -803,21 +757,21 @@
unsigned len = S->getByteLength();
unsigned j = 0;
+ // Copy bytes from the string literal into the target array. Trailing bytes
+ // in the array that are not covered by the string literal are initialized
+ // to zero.
for (; i < Size; ++i, ++j) {
+ if (j >= len)
+ break;
+
SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
- // Copy bytes from the string literal into the target array. Trailing
- // bytes in the array that are not covered by the string literal are
- // initialized to zero.
- SVal V = (j < len)
- ? NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true)
- : NonLoc::MakeVal(getBasicVals(), 0, sizeof(char)*8, true);
-
- store = Bind(store, loc::MemRegionVal(ER), V);
+ SVal V = NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true);
+ St = Bind(St, loc::MemRegionVal(ER), V);
}
- return store;
+ return StateMgr.MakeStateWithStore(St, store);
}
@@ -825,79 +779,25 @@
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
- for (; i < Size; ++i) {
- SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
- ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
-
- store = Bind(store, loc::MemRegionVal(ER), (VI!=VE) ? *VI : UndefinedVal());
+ for (; i < Size; ++i, ++VI) {
// The init list might be shorter than the array decl.
- if (VI != VE) ++VI;
- }
-
- return store;
-}
-
-// Bind all elements of the array to some value.
-Store RegionStoreManager::BindArrayToVal(Store store, const TypedRegion* BaseR,
- SVal V){
-
- // FIXME: Verify we want getRValueType.
- QualType T = BaseR->getRValueType(getContext());
- assert(T->isArrayType());
-
- // Only handle constant size array for now.
- if (ConstantArrayType* CAT=dyn_cast<ConstantArrayType>(T.getTypePtr())) {
+ if (VI == VE)
+ break;
- llvm::APInt Size = CAT->getSize();
- llvm::APInt i = llvm::APInt::getNullValue(Size.getBitWidth());
-
- for (; i != Size; ++i) {
- nonloc::ConcreteInt Idx(getBasicVals().getValue(llvm::APSInt(i, false)));
-
- ElementRegion* ER = MRMgr.getElementRegion(Idx, BaseR);
-
- if (CAT->getElementType()->isStructureType())
- store = BindStructToVal(store, ER, V);
- else
- store = Bind(store, loc::MemRegionVal(ER), V);
- }
- }
-
- return store;
-}
-
-Store RegionStoreManager::BindArrayToSymVal(Store store,
- const TypedRegion* BaseR) {
-
- // FIXME: Verify we want getRValueType.
- QualType T = BaseR->getRValueType(getContext());
- assert(T->isArrayType());
-
- if (ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T.getTypePtr())) {
- llvm::APInt Size = CAT->getSize();
- llvm::APInt i = llvm::APInt::getNullValue(Size.getBitWidth());
- for (; i != Size; ++i) {
- nonloc::ConcreteInt Idx(getBasicVals().getValue(llvm::APSInt(i, false)));
-
- ElementRegion* ER = MRMgr.getElementRegion(Idx, BaseR);
+ SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
+ ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
- if (CAT->getElementType()->isStructureType()) {
- store = BindStructToSymVal(store, ER);
- }
- else {
- SVal V = SVal::getSymbolValue(getSymbolManager(), BaseR,
- &Idx.getValue(), CAT->getElementType());
- store = Bind(store, loc::MemRegionVal(ER), V);
- }
- }
+ if (CAT->getElementType()->isStructureType())
+ St = BindStruct(St, ER, *VI);
+ else
+ St = Bind(St, Loc::MakeVal(ER), *VI);
}
- return store;
+ return StateMgr.MakeStateWithStore(St, store);
}
-Store RegionStoreManager::InitializeStruct(Store store, const TypedRegion* R,
- SVal Init) {
-
+const GRState*
+RegionStoreManager::BindStruct(const GRState* St, const TypedRegion* R, SVal V){
// FIXME: Verify that we should use getRValueType or getLValueType.
QualType T = R->getRValueType(getContext());
assert(T->isStructureType());
@@ -906,102 +806,35 @@
RecordDecl* RD = RT->getDecl();
assert(RD->isDefinition());
- nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
+ nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
- for (; FI != FE; ++FI) {
- QualType FTy = (*FI)->getType();
- FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
+ for (; FI != FE; ++FI, ++VI) {
- if (Loc::IsLocType(FTy) || FTy->isIntegerType()) {
- if (VI != VE) {
- store = Bind(store, loc::MemRegionVal(FR), *VI);
- ++VI;
- } else
- store = Bind(store, loc::MemRegionVal(FR), UndefinedVal());
- }
- else if (FTy->isArrayType()) {
- if (VI != VE) {
- store = InitializeArray(store, FR, *VI);
- ++VI;
- } else
- store = BindArrayToVal(store, FR, UndefinedVal());
- }
- else if (FTy->isStructureType()) {
- if (VI != VE) {
- store = InitializeStruct(store, FR, *VI);
- ++VI;
- } else
- store = BindStructToVal(store, FR, UndefinedVal());
+ // 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);
+ //St = state.set<RegionDefaultValue>(R, NonLoc::MakeVal(getBasicVals(), 0,
+ // false));
+ break;
}
- }
- return store;
-}
-// Bind all fields of the struct to some value.
-Store RegionStoreManager::BindStructToVal(Store store, const TypedRegion* BaseR,
- SVal V) {
-
- // FIXME: Verify that we should use getLValueType or getRValueType.
- QualType T = BaseR->getRValueType(getContext());
- assert(T->isStructureType());
-
- const RecordType* RT = cast<RecordType>(T.getTypePtr());
- RecordDecl* RD = RT->getDecl();
- assert(RD->isDefinition());
-
- RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ QualType FTy = (*FI)->getType();
+ FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
- for (; I != E; ++I) {
-
- QualType FTy = (*I)->getType();
- FieldRegion* FR = MRMgr.getFieldRegion(*I, BaseR);
+ if (Loc::IsLocType(FTy) || FTy->isIntegerType())
+ St = Bind(St, Loc::MakeVal(FR), *VI);
- if (Loc::IsLocType(FTy) || FTy->isIntegerType()) {
- store = Bind(store, loc::MemRegionVal(FR), V);
+ else if (FTy->isArrayType())
+ St = BindArray(St, FR, *VI);
- } else if (FTy->isArrayType()) {
- store = BindArrayToVal(store, FR, V);
-
- } else if (FTy->isStructureType()) {
- store = BindStructToVal(store, FR, V);
- }
- }
-
- return store;
-}
-
-Store RegionStoreManager::BindStructToSymVal(Store store,
- const TypedRegion* BaseR) {
-
- // FIXME: Verify that we should use getLValueType or getRValueType
- QualType T = BaseR->getRValueType(getContext());
- assert(T->isStructureType());
-
- const RecordType* RT = cast<RecordType>(T.getTypePtr());
- RecordDecl* RD = RT->getDecl();
- assert(RD->isDefinition());
-
- RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-
- for (; I != E; ++I) {
- QualType FTy = (*I)->getType();
- FieldRegion* FR = MRMgr.getFieldRegion(*I, BaseR);
-
- if (Loc::IsLocType(FTy) || FTy->isIntegerType()) {
- store = Bind(store, loc::MemRegionVal(FR),
- SVal::getSymbolValue(getSymbolManager(), BaseR, *I, FTy));
- }
- else if (FTy->isArrayType()) {
- store = BindArrayToSymVal(store, FR);
- }
- else if (FTy->isStructureType()) {
- store = BindStructToSymVal(store, FR);
- }
+ else if (FTy->isStructureType())
+ St = BindStruct(St, FR, *VI);
}
- return store;
+ return St;
}
const GRState* RegionStoreManager::AddRegionView(const GRState* St,
Modified: cfe/trunk/lib/Analysis/SVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SVals.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/SVals.cpp (original)
+++ cfe/trunk/lib/Analysis/SVals.cpp Sat Dec 20 00:32:12 2008
@@ -242,6 +242,11 @@
//===----------------------------------------------------------------------===//
// Utility methods for constructing Non-Locs.
//===----------------------------------------------------------------------===//
+
+NonLoc NonLoc::MakeVal(SymbolRef sym) {
+ return nonloc::SymbolVal(sym);
+}
+
NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, unsigned X,
bool isUnsigned) {
return nonloc::ConcreteInt(BasicVals.getValue(X, sizeof(unsigned)*8,
@@ -281,6 +286,14 @@
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}
+SVal SVal::MakeSymbolValue(SymbolManager& SymMgr, const MemRegion* R,
+ QualType T) {
+ if (Loc::IsLocType(T))
+ return Loc::MakeVal(SymMgr.getSymbol(R));
+ else
+ return NonLoc::MakeVal(SymMgr.getSymbol(R));
+}
+
SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
QualType T = D->getType();
@@ -320,6 +333,8 @@
Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }
+Loc Loc::MakeVal(SymbolRef sym) { return loc::SymbolVal(sym); }
+
//===----------------------------------------------------------------------===//
// Pretty-Printing.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Analysis/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SymbolManager.cpp?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/SymbolManager.cpp (original)
+++ cfe/trunk/lib/Analysis/SymbolManager.cpp Sat Dec 20 00:32:12 2008
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/SymbolManager.h"
+#include "clang/Analysis/PathSensitive/MemRegion.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -21,14 +22,35 @@
os << getNumber();
}
-SymbolRef SymbolManager::getSymbol(VarDecl* D) {
+SymbolRef SymbolManager::getSymbol(const MemRegion* R) {
+ switch (R->getKind()) {
+ case MemRegion::VarRegionKind:
+ return getSymbol(cast<VarRegion>(R)->getDecl());
+
+ case MemRegion::ElementRegionKind: {
+ const ElementRegion* ER = cast<ElementRegion>(R);
+ const llvm::APSInt& Idx =
+ cast<nonloc::ConcreteInt>(ER->getIndex()).getValue();
+ return getElementSymbol(ER->getSuperRegion(), &Idx);
+ }
+
+ case MemRegion::FieldRegionKind: {
+ const FieldRegion* FR = cast<FieldRegion>(R);
+ return getFieldSymbol(FR->getSuperRegion(), FR->getDecl());
+ }
+ default:
+ assert(0 && "unprocessed region");
+ }
+}
+
+SymbolRef SymbolManager::getSymbol(const VarDecl* D) {
assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ||
D->hasGlobalStorage());
llvm::FoldingSetNodeID profile;
- ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
+ const ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
if (PD)
SymbolDataParmVar::Profile(profile, PD);
Modified: cfe/trunk/test/Analysis/null-deref-ps.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/null-deref-ps.c?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/null-deref-ps.c (original)
+++ cfe/trunk/test/Analysis/null-deref-ps.c Sat Dec 20 00:32:12 2008
@@ -1,5 +1,5 @@
-// RUN: clang -std=gnu99 -checker-simple -verify %s &&
-// RUN: clang -std=gnu99 -checker-simple -analyzer-store-region -verify %s
+// RUN: clang -std=gnu99 -checker-simple -verify %s
+// DISABLE: clang -std=gnu99 -checker-simple -analyzer-store-region -verify %s
#include<stdint.h>
#include <assert.h>
Modified: cfe/trunk/test/Analysis/uninit-vals-ps-region.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps-region.c?rev=61274&r1=61273&r2=61274&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps-region.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps-region.c Sat Dec 20 00:32:12 2008
@@ -1,4 +1,4 @@
-// RUN: clang -checker-simple -analyzer-store-region -verify %s
+// DISABLE: clang -checker-simple -analyzer-store-region -verify %s
struct s {
int data;
More information about the cfe-commits
mailing list