diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-07-10 22:03:41 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-07-10 22:03:41 +0000 |
commit | 4323a57627e796dcfdfdb7d47672dc09ed308eda (patch) | |
tree | d134b1a85f9ec16f0db46f4b7f6bc4e1ead64b25 /lib/Analysis | |
parent | e5690319a0e834b9bd9dcb5e444e59ecc5da3105 (diff) |
Refactored most of the "Store" piece of ValueState into a Store type. The
current store implementation is now encapsulated by BasicStore.
These changes prompted some long due constification of ValueState. Much of the
diffs in this patch include adding "const" qualifiers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53423 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/BasicObjCFoundationChecks.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 141 | ||||
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 62 | ||||
-rw-r--r-- | lib/Analysis/GRCoreEngine.cpp | 18 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 133 | ||||
-rw-r--r-- | lib/Analysis/GRSimpleVals.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/GRTransferFuncs.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/ValueState.cpp | 151 |
9 files changed, 296 insertions, 233 deletions
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp index 1667a21494..4475ed2bc5 100644 --- a/lib/Analysis/BasicObjCFoundationChecks.cpp +++ b/lib/Analysis/BasicObjCFoundationChecks.cpp @@ -107,7 +107,7 @@ class VISIBILITY_HIDDEN BasicObjCFoundationChecks : public GRSimpleAPICheck { typedef std::vector<BugReport*> ErrorsTy; ErrorsTy Errors; - RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } + RVal GetRVal(const ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } bool isNSString(ObjCInterfaceType* T, const char* suffix); bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME); @@ -338,8 +338,8 @@ class VISIBILITY_HIDDEN AuditCFNumberCreate : public GRSimpleAPICheck { IdentifierInfo* II; ValueStateManager* VMgr; - RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } - RVal GetRVal(ValueState* St, LVal LV) { return VMgr->GetRVal(St, LV); } + RVal GetRVal(const ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); } + RVal GetRVal(const ValueState* St, LVal LV) { return VMgr->GetRVal(St, LV); } public: diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp new file mode 100644 index 0000000000..38c1db70f1 --- /dev/null +++ b/lib/Analysis/BasicStore.cpp @@ -0,0 +1,141 @@ +//== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defined the BasicStore and BasicStoreManager classes. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/BasicStore.h" +#include "llvm/ADT/ImmutableMap.h" +#include "llvm/Support/Compiler.h" + +using namespace clang; + +namespace { + +class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager { + typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy; + VarBindingsTy::Factory VBFactory; + +public: + BasicStoreManager(llvm::BumpPtrAllocator& A) : VBFactory(A) {} + virtual ~BasicStoreManager() {} + + virtual RVal GetRVal(Store St, LVal LV, QualType T); + virtual Store SetRVal(Store St, LVal LV, RVal V); + virtual Store Remove(Store St, LVal LV); + + virtual Store getInitialStore() { + return VBFactory.GetEmptyMap().getRoot(); + } +}; + +} // end anonymous namespace + + +StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A) { + return new BasicStoreManager(A); +} + +RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { + + if (isa<UnknownVal>(LV)) + return UnknownVal(); + + assert (!isa<UndefinedVal>(LV)); + + switch (LV.getSubKind()) { + + case lval::DeclValKind: { + VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St)); + VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl()); + return T ? *T : UnknownVal(); + } + + case lval::SymbolValKind: { + + // FIXME: This is a broken representation of memory, and is prone + // to crashing the analyzer when addresses to symbolic values are + // passed through casts. We need a better representation of symbolic + // memory (or just memory in general); probably we should do this + // as a plugin class (similar to GRTransferFuncs). + +#if 0 + const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV); + assert (T.getTypePtr()); + + // Punt on "symbolic" function pointers. + if (T->isFunctionType()) + return UnknownVal(); + + if (T->isPointerType()) + return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol())); + else + return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol())); +#endif + + return UnknownVal(); + } + + case lval::ConcreteIntKind: + // Some clients may call GetRVal with such an option simply because + // they are doing a quick scan through their LVals (potentially to + // invalidate their bindings). Just return Undefined. + return UndefinedVal(); + + case lval::ArrayOffsetKind: + case lval::FieldOffsetKind: + return UnknownVal(); + + case lval::FuncValKind: + return LV; + + case lval::StringLiteralValKind: + // FIXME: Implement better support for fetching characters from strings. + return UnknownVal(); + + default: + assert (false && "Invalid LVal."); + break; + } + + return UnknownVal(); +} + +Store BasicStoreManager::SetRVal(Store St, LVal LV, RVal V) { + + VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St)); + + switch (LV.getSubKind()) { + + case lval::DeclValKind: + return V.isUnknown() + ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot() + : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot(); + + default: + assert ("SetRVal for given LVal type not yet implemented."); + return St; + } +} + +Store BasicStoreManager::Remove(Store St, LVal LV) { + + VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St)); + + switch (LV.getSubKind()) { + + case lval::DeclValKind: + return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot(); + + default: + assert ("Remove for given LVal type not yet implemented."); + return St; + } +} diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index fba31f81af..081e7925ee 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -327,7 +327,7 @@ static void HandleNotableSymbol(ExplodedNode<ValueState>* N, Stmt* S, PathDiagnostic& PD) { ExplodedNode<ValueState>* Pred = N->pred_empty() ? 0 : *N->pred_begin(); - ValueState* PrevSt = Pred ? Pred->getState() : 0; + const ValueState* PrevSt = Pred ? Pred->getState() : 0; if (!PrevSt) return; @@ -335,7 +335,7 @@ static void HandleNotableSymbol(ExplodedNode<ValueState>* N, Stmt* S, // Look at the variable bindings of the current state that map to the // specified symbol. Are any of them not in the previous state. - ValueState* St = N->getState(); + const ValueState* St = N->getState(); ValueStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager(); // FIXME: Later generalize for a broader memory model. @@ -633,7 +633,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) { - ValueState* St = N->getState(); + const ValueState* St = N->getState(); // Scan the lval bindings, and see if a "notable" symbol has a new // lval binding. diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 1a57306f86..4de91daa1b 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1135,8 +1135,8 @@ private: public: - static RefBindings GetRefBindings(ValueState& StImpl) { - return RefBindings((RefBindings::TreeTy*) StImpl.CheckerState); + static RefBindings GetRefBindings(const ValueState& StImpl) { + return RefBindings((const RefBindings::TreeTy*) StImpl.CheckerState); } private: @@ -1156,14 +1156,15 @@ private: GRStmtNodeBuilder<ValueState>& Builder, Expr* NodeExpr, Expr* ErrorExpr, ExplodedNode<ValueState>* Pred, - ValueState* St, + const ValueState* St, RefVal::Kind hasErr, SymbolID Sym); - ValueState* HandleSymbolDeath(ValueStateManager& VMgr, ValueState* St, - SymbolID sid, RefVal V, bool& hasLeak); + const ValueState* HandleSymbolDeath(ValueStateManager& VMgr, + const ValueState* St, + SymbolID sid, RefVal V, bool& hasLeak); - ValueState* NukeBinding(ValueStateManager& VMgr, ValueState* St, - SymbolID sid); + const ValueState* NukeBinding(ValueStateManager& VMgr, const ValueState* St, + SymbolID sid); public: @@ -1226,7 +1227,7 @@ public: GRExprEngine& Engine, GRStmtNodeBuilder<ValueState>& Builder, Expr* E, ExplodedNode<ValueState>* Pred, - ValueState* St, RVal TargetLV, RVal Val); + const ValueState* St, RVal TargetLV, RVal Val); // End-of-path. virtual void EvalEndPath(GRExprEngine& Engine, @@ -1237,7 +1238,7 @@ public: GRStmtNodeBuilder<ValueState>& Builder, ExplodedNode<ValueState>* Pred, Stmt* S, - ValueState* St, + const ValueState* St, const ValueStateManager::DeadSymbolsTy& Dead); // Return statements. @@ -1249,8 +1250,9 @@ public: // Assumptions. - virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* St, - RVal Cond, bool Assumption, bool& isFeasible); + virtual const ValueState* EvalAssume(GRExprEngine& Engine, + const ValueState* St, RVal Cond, + bool Assumption, bool& isFeasible); // Error iterators. @@ -1304,7 +1306,7 @@ void CFRefCount::ProcessNonLeakError(ExplodedNodeSet<ValueState>& Dst, GRStmtNodeBuilder<ValueState>& Builder, Expr* NodeExpr, Expr* ErrorExpr, ExplodedNode<ValueState>* Pred, - ValueState* St, + const ValueState* St, RefVal::Kind hasErr, SymbolID Sym) { Builder.BuildSinks = true; GRExprEngine::NodeTy* N = Builder.MakeNode(Dst, NodeExpr, Pred, St); @@ -1368,7 +1370,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst, // Get the state. ValueStateManager& StateMgr = Eng.getStateManager(); - ValueState* St = Builder.GetState(Pred); + const ValueState* St = Builder.GetState(Pred); // Evaluate the effect of the arguments. ValueState StVals = *St; @@ -1429,7 +1431,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst, unsigned Count = Builder.getCurrentBlockCount(); SymbolID NewSym = Eng.getSymbolManager().getConjuredSymbol(*I, Count); - StateMgr.BindVar(StVals, DV->getDecl(), + StateMgr.SetRVal(StVals, *DV, LVal::IsLValType(DV->getDecl()->getType()) ? cast<RVal>(lval::SymbolVal(NewSym)) : cast<RVal>(nonlval::SymbolVal(NewSym))); @@ -1596,7 +1598,7 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst, // FIXME: Wouldn't it be great if this code could be reduced? It's just // a chain of lookups. - ValueState* St = Builder.GetState(Pred); + const ValueState* St = Builder.GetState(Pred); RVal V = Eng.getStateManager().GetRVal(St, Receiver ); if (isa<lval::SymbolVal>(V)) { @@ -1630,7 +1632,7 @@ void CFRefCount::EvalStore(ExplodedNodeSet<ValueState>& Dst, GRExprEngine& Eng, GRStmtNodeBuilder<ValueState>& Builder, Expr* E, ExplodedNode<ValueState>* Pred, - ValueState* St, RVal TargetLV, RVal Val) { + const ValueState* St, RVal TargetLV, RVal Val) { // Check if we have a binding for "Val" and if we are storing it to something // we don't understand or otherwise the value "escapes" the function. @@ -1663,8 +1665,9 @@ void CFRefCount::EvalStore(ExplodedNodeSet<ValueState>& Dst, } -ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr, ValueState* St, - SymbolID sid) { +const ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr, + const ValueState* St, + SymbolID sid) { ValueState StImpl = *St; RefBindings B = GetRefBindings(StImpl); StImpl.CheckerState = RefBFactory.Remove(B, sid).getRoot(); @@ -1673,8 +1676,8 @@ ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr, ValueState* St, // End-of-path. -ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr, - ValueState* St, SymbolID sid, +const ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr, + const ValueState* St, SymbolID sid, RefVal V, bool& hasLeak) { hasLeak = V.isOwned() || @@ -1693,7 +1696,7 @@ ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr, void CFRefCount::EvalEndPath(GRExprEngine& Eng, GREndPathNodeBuilder<ValueState>& Builder) { - ValueState* St = Builder.getState(); + const ValueState* St = Builder.getState(); RefBindings B = GetRefBindings(*St); llvm::SmallVector<SymbolID, 10> Leaked; @@ -1731,7 +1734,7 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<ValueState>& Dst, GRStmtNodeBuilder<ValueState>& Builder, ExplodedNode<ValueState>* Pred, Stmt* S, - ValueState* St, + const ValueState* St, const ValueStateManager::DeadSymbolsTy& Dead) { // FIXME: a lot of copy-and-paste from EvalEndPath. Refactor. @@ -1784,7 +1787,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<ValueState>& Dst, if (!RetE) return; ValueStateManager& StateMgr = Eng.getStateManager(); - ValueState* St = Builder.GetState(Pred); + const ValueState* St = Builder.GetState(Pred); RVal V = StateMgr.GetRVal(St, RetE); if (!isa<lval::SymbolVal>(V)) @@ -1831,9 +1834,10 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<ValueState>& Dst, // Assumptions. -ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng, ValueState* St, - RVal Cond, bool Assumption, - bool& isFeasible) { +const ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng, + const ValueState* St, + RVal Cond, bool Assumption, + bool& isFeasible) { // FIXME: We may add to the interface of EvalAssume the list of symbols // whose assumptions have changed. For now we just iterate through the @@ -2136,8 +2140,8 @@ PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode<ValueState>* N, // Check if the type state has changed. - ValueState* PrevSt = PrevN->getState(); - ValueState* CurrSt = N->getState(); + const ValueState* PrevSt = PrevN->getState(); + const ValueState* CurrSt = N->getState(); CFRefCount::RefBindings PrevB = CFRefCount::GetRefBindings(*PrevSt); CFRefCount::RefBindings CurrB = CFRefCount::GetRefBindings(*CurrSt); @@ -2275,7 +2279,7 @@ GetAllocationSite(ExplodedNode<ValueState>* N, SymbolID Sym) { VarDecl* FirstDecl = 0; while (N) { - ValueState* St = N->getState(); + const ValueState* St = N->getState(); RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState); if (!B.lookup(Sym)) diff --git a/lib/Analysis/GRCoreEngine.cpp b/lib/Analysis/GRCoreEngine.cpp index a4bb7fa631..548c4bf161 100644 --- a/lib/Analysis/GRCoreEngine.cpp +++ b/lib/Analysis/GRCoreEngine.cpp @@ -255,8 +255,8 @@ void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B, /// GenerateNode - Utility method to generate nodes, hook up successors, /// and add nodes to the worklist. -void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, void* State, - ExplodedNodeImpl* Pred) { +void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State, + ExplodedNodeImpl* Pred) { bool IsNew; ExplodedNodeImpl* Node = G->getNodeImpl(Loc, State, &IsNew); @@ -321,7 +321,7 @@ static inline ProgramPoint GetPostLoc(Stmt* S, ProgramPoint::Kind K) { } ExplodedNodeImpl* -GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, void* State, +GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, const void* State, ExplodedNodeImpl* Pred, ProgramPoint::Kind K) { @@ -342,7 +342,7 @@ GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, void* State, return NULL; } -ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State, +ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State, bool branch) { bool IsNew; @@ -374,7 +374,7 @@ GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() { ExplodedNodeImpl* GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I, - void* St, + const void* St, bool isSink) { bool IsNew; @@ -399,7 +399,8 @@ GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I, ExplodedNodeImpl* -GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, void* St) { +GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, + const void* St) { bool IsNew; @@ -418,7 +419,8 @@ GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, void* St) { ExplodedNodeImpl* -GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(void* St, bool isSink) { +GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St, + bool isSink) { // Get the block for the default case. assert (Src->succ_rbegin() != Src->succ_rend()); @@ -448,7 +450,7 @@ GREndPathNodeBuilderImpl::~GREndPathNodeBuilderImpl() { if (!HasGeneratedNode) generateNodeImpl(Pred->State); } -ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(void* State) { +ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(const void* State){ HasGeneratedNode = true; bool IsNew; diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index c4eddb9993..96e7fae7e3 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -18,6 +18,8 @@ #include "clang/Basic/SourceManager.h" #include "llvm/Support/Streams.h" +#include "clang/Analysis/PathSensitive/BasicStore.h" + #ifndef NDEBUG #include "llvm/Support/GraphWriter.h" #include <sstream> @@ -44,7 +46,8 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, G(CoreEngine.getGraph()), Liveness(L), Builder(NULL), - StateMgr(G.getContext(), G.getAllocator()), + StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()), + G.getAllocator()), BasicVals(StateMgr.getBasicValueFactory()), TF(NULL), // FIXME SymMgr(StateMgr.getSymbolManager()), @@ -127,7 +130,7 @@ void GRExprEngine::AddObjCMessageExprCheck(GRSimpleAPICheck* A) { MsgExprChecks.push_back(A); } -ValueState* GRExprEngine::getInitialState() { +const ValueState* GRExprEngine::getInitialState() { // The LiveVariables information already has a compilation of all VarDecls // used in the function. Iterate through this set, and "symbolicate" @@ -144,11 +147,11 @@ ValueState* GRExprEngine::getInitialState() { if (VarDecl* VD = dyn_cast<VarDecl>(SD)) { if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) { RVal X = RVal::GetSymbolValue(SymMgr, VD); - StateMgr.BindVar(StateImpl, VD, X); + StateMgr.SetRVal(StateImpl, lval::DeclVal(VD), X); } } else if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(SD)) { RVal X = RVal::GetSymbolValue(SymMgr, IPD); - StateMgr.BindVar(StateImpl, IPD, X); + StateMgr.SetRVal(StateImpl, lval::DeclVal(IPD), X); } @@ -157,7 +160,8 @@ ValueState* GRExprEngine::getInitialState() { return StateMgr.getPersistentState(StateImpl); } -ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) { +const ValueState* GRExprEngine::SetRVal(const ValueState* St, Expr* Ex, + RVal V) { bool isBlkExpr = false; @@ -285,7 +289,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { break; } else if (B->getOpcode() == BinaryOperator::Comma) { - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); MakeNode(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS()))); break; } @@ -364,7 +368,7 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { case Stmt::StmtExprClass: { StmtExpr* SE = cast<StmtExpr>(S); - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); // FIXME: Not certain if we can have empty StmtExprs. If so, we should // probably just remove these from the CFG. @@ -420,7 +424,7 @@ void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { // Block entrance. (Update counters). //===----------------------------------------------------------------------===// -bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*, +bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ValueState*, GRBlockCounter BC) { return BC.getNumVisited(B->getBlockID()) < 3; @@ -430,8 +434,9 @@ bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*, // Branch processing. //===----------------------------------------------------------------------===// -ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator, - bool branchTaken) { +const ValueState* GRExprEngine::MarkBranch(const ValueState* St, + Stmt* Terminator, + bool branchTaken) { switch (Terminator->getStmtClass()) { default: @@ -488,7 +493,8 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder) { // Remove old bindings for subexpressions. - ValueState* PrevState = StateMgr.RemoveSubExprBindings(builder.getState()); + const ValueState* PrevState = + StateMgr.RemoveSubExprBindings(builder.getState()); // Check for NULL conditions; e.g. "for(;;)" if (!Condition) { @@ -523,7 +529,7 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, // Process the true branch. bool isFeasible = false; - ValueState* St = Assume(PrevState, V, true, isFeasible); + const ValueState* St = Assume(PrevState, V, true, isFeasible); if (isFeasible) builder.generateNode(MarkBranch(St, Term, true), true); @@ -545,7 +551,7 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, /// nodes by processing the 'effects' of a computed goto jump. void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) { - ValueState* St = builder.getState(); + const ValueState* St = builder.getState(); RVal V = GetRVal(St, builder.getTarget()); // Three possibilities: @@ -592,7 +598,7 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex)); - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); RVal X = GetBlkExprRVal(St, Ex); assert (X.isUndef()); @@ -613,7 +619,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) { typedef SwitchNodeBuilder::iterator iterator; - ValueState* St = builder.getState(); + const ValueState* St = builder.getState(); Expr* CondE = builder.getCondition(); RVal CondV = GetRVal(St, CondE); @@ -623,7 +629,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) { return; } - ValueState* DefaultSt = St; + const ValueState* DefaultSt = St; // While most of this can be assumed (such as the signedness), having it // just computed makes sure everything makes the same assumptions end-to-end. @@ -670,7 +676,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) { // Now "assume" that the case matches. bool isFeasible = false; - ValueState* StNew = Assume(St, Res, true, isFeasible); + const ValueState* StNew = Assume(St, Res, true, isFeasible); if (isFeasible) { builder.generateCaseStmtNode(I, StNew); @@ -720,7 +726,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, assert (B == CurrentStmt && getCFG().isBlkExpr(B)); - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); RVal X = GetBlkExprRVal(St, B); assert (X.isUndef()); @@ -748,7 +754,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, // the payoff is not likely to be large. Instead, we do eager evaluation. bool isFeasible = false; - ValueState* NewState = Assume(St, X, true, isFeasible); + const ValueState* NewState = Assume(St, X, true, isFeasible); if (isFeasible) MakeNode(Dst, B, Pred, @@ -778,7 +784,7 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst, bool asLVal) { - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); RVal X = RVal::MakeVal(BasicVals, D); if (asLVal) @@ -814,7 +820,7 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A, NodeTy* Pred, for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) { - ValueState* St = GetState(*I2); + const ValueState* St = GetState(*I2); RVal BaseV = GetRVal(St, Base); RVal IdxV = GetRVal(St, Idx); @@ -853,7 +859,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, VisitLVal(Base, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal BaseV = GetRVal(St, Base); RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base), @@ -871,7 +877,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal BaseV = GetRVal(St, Base); if (LVal::IsLValType(Base->getType())) { @@ -900,7 +906,7 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, } void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred, - ValueState* St, RVal location, RVal Val) { + const ValueState* St, RVal location, RVal Val) { assert (Builder && "GRStmtNodeBuilder must be defined."); @@ -930,7 +936,8 @@ void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred, } void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred, - ValueState* St, RVal location, bool CheckOnly) { + const ValueState* St, RVal location, + bool CheckOnly) { // Evaluate the location (checks for bad dereferences). @@ -958,9 +965,9 @@ void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred, Ex->getType()))); } -ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, - ValueState* St, RVal location, - bool isLoad) { +const ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, + const ValueState* St, + RVal location, bool isLoad) { // Check for loads/stores from/to undefined values. if (location.isUndef()) { @@ -990,12 +997,12 @@ ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, // "Assume" that the pointer is not NULL. bool isFeasibleNotNull = false; - ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull); + const ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull); // "Assume" that the pointer is NULL. bool isFeasibleNull = false; - ValueState* StNull = Assume(St, LV, false, isFeasibleNull); + const ValueState* StNull = Assume(St, LV, false, isFeasibleNull); if (isFeasibleNull) { @@ -1053,7 +1060,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred, // Finally, evaluate the function call. for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) { - ValueState* St = GetState(*DI); + const ValueState* St = GetState(*DI); RVal L = GetRVal(St, Callee); // FIXME: Add support for symbolic function calls (calls involving @@ -1246,7 +1253,7 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, // FIXME: More logic for the processing the method call. - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); bool RaisesException = false; @@ -1391,7 +1398,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) { NodeTy* N = *I1; - ValueState* St = GetState(N); + const ValueState* St = GetState(N); RVal V = GetRVal(St, Ex); // Unknown? @@ -1470,7 +1477,7 @@ void GRExprEngine::VisitDeclStmtAux(DeclStmt* DS, ScopedDecl* D, for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); if (!Ex && VD->hasGlobalStorage()) { @@ -1601,7 +1608,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal location = GetRVal(St, Ex); if (asLVal) @@ -1630,7 +1637,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // For all other types, UnaryOperator::Real is an identity operation. assert (U->getType() == Ex->getType()); - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex))); } @@ -1653,7 +1660,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, // For all other types, UnaryOperator::Float returns 0. assert (Ex->getType()->isIntegerType()); - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal X = NonLVal::MakeVal(BasicVals, 0, Ex->getType()); MakeNode(Dst, U, *I, SetRVal(St, U, X)); } @@ -1679,7 +1686,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, Visit(Ex, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex))); } @@ -1694,7 +1701,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, VisitLVal(Ex, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal V = GetRVal(St, Ex); St = SetRVal(St, U, V); MakeNode(Dst, U, *I, St); @@ -1713,7 +1720,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, Visit(Ex, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal V = GetRVal(St, Ex); if (V.isUnknownOrUndef()) { @@ -1771,7 +1778,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, return; uint64_t size = getContext().getTypeSize(T) / 8; - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, size, U->getType())); MakeNode(Dst, U, Pred, St); @@ -1788,7 +1795,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) { - ValueState* St = GetState(*I); + const ValueState* St = GetState(*I); RVal V1 = GetRVal(St, Ex); // Perform a load. @@ -1855,7 +1862,7 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A, // which interprets the inline asm and stores proper results in the // outputs. - ValueState* St = GetState(Pred); + const ValueState* St = GetState(Pred); for (AsmStmt::outputs_iterator OI = A-> |