[cfe-commits] r53423 - in /cfe/trunk: include/clang/Analysis/PathSensitive/ lib/Analysis/
Ted Kremenek
kremenek at apple.com
Thu Jul 10 15:03:41 PDT 2008
Author: kremenek
Date: Thu Jul 10 17:03:41 2008
New Revision: 53423
URL: http://llvm.org/viewvc/llvm-project?rev=53423&view=rev
Log:
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.
Added:
cfe/trunk/include/clang/Analysis/PathSensitive/BasicStore.h
cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
cfe/trunk/lib/Analysis/BasicStore.cpp
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h
cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
cfe/trunk/lib/Analysis/BugReporter.cpp
cfe/trunk/lib/Analysis/CFRefCount.cpp
cfe/trunk/lib/Analysis/GRCoreEngine.cpp
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/lib/Analysis/GRSimpleVals.cpp
cfe/trunk/lib/Analysis/GRTransferFuncs.cpp
cfe/trunk/lib/Analysis/ValueState.cpp
Added: cfe/trunk/include/clang/Analysis/PathSensitive/BasicStore.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BasicStore.h?rev=53423&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BasicStore.h (added)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BasicStore.h Thu Jul 10 17:03:41 2008
@@ -0,0 +1,27 @@
+//== BasicStore.h - 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BASICSTORE_H
+#define LLVM_CLANG_ANALYSIS_BASICSTORE_H
+
+#include "clang/Analysis/PathSensitive/Store.h"
+
+namespace llvm {
+ class llvm::BumpPtrAllocator;
+}
+
+namespace clang {
+ StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc);
+}
+
+#endif
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Thu Jul 10 17:03:41 2008
@@ -95,10 +95,8 @@
/// with this node.
const ProgramPoint Location;
- /// State - The state associated with this node. Normally this value
- /// is immutable, but we anticipate there will be times when algorithms
- /// that directly manipulate the analysis graph will need to change it.
- void* State;
+ /// State - The state associated with this node.
+ const void* State;
/// Preds - The predecessors of this node.
NodeGroup Preds;
@@ -107,7 +105,7 @@
NodeGroup Succs;
/// Construct a ExplodedNodeImpl with the provided location and state.
- explicit ExplodedNodeImpl(const ProgramPoint& loc, void* state)
+ explicit ExplodedNodeImpl(const ProgramPoint& loc, const void* state)
: Location(loc), State(state) {}
/// addPredeccessor - Adds a predecessor to the current node, and
@@ -146,19 +144,19 @@
public:
/// Construct a ExplodedNodeImpl with the given node ID, program edge,
/// and state.
- explicit ExplodedNode(const ProgramPoint& loc, StateTy* St)
+ explicit ExplodedNode(const ProgramPoint& loc, const StateTy* St)
: ExplodedNodeImpl(loc, St) {}
/// getState - Returns the state associated with the node.
- inline StateTy* getState() const {
- return static_cast<StateTy*>(State);
+ inline const StateTy* getState() const {
+ return static_cast<const StateTy*>(State);
}
// Profiling (for FoldingSet).
static inline void Profile(llvm::FoldingSetNodeID& ID,
const ProgramPoint& Loc,
- StateTy* state) {
+ const StateTy* state) {
ID.Add(Loc);
GRTrait<StateTy>::Profile(ID, state);
}
@@ -241,7 +239,8 @@
/// getNodeImpl - Retrieve the node associated with a (Location,State)
/// pair, where 'State' is represented as an opaque void*. This method
/// is intended to be used only by GRCoreEngineImpl.
- virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L, void* State,
+ virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
+ const void* State,
bool* IsNew) = 0;
virtual ExplodedGraphImpl* MakeEmptyGraph() const = 0;
@@ -300,9 +299,10 @@
protected:
virtual ExplodedNodeImpl* getNodeImpl(const ProgramPoint& L,
- void* State, bool* IsNew) {
+ const void* State,
+ bool* IsNew) {
- return getNode(L, static_cast<StateTy*>(State), IsNew);
+ return getNode(L, static_cast<const StateTy*>(State), IsNew);
}
virtual ExplodedGraphImpl* MakeEmptyGraph() const {
@@ -317,7 +317,8 @@
/// where the 'Location' is a ProgramPoint in the CFG. If no node for
/// this pair exists, it is created. IsNew is set to true if
/// the node was freshly created.
- NodeTy* getNode(const ProgramPoint& L, StateTy* State, bool* IsNew = NULL) {
+ NodeTy* getNode(const ProgramPoint& L, const StateTy* State,
+ bool* IsNew = NULL) {
// Profile 'State' to determine if we already have an existing node.
llvm::FoldingSetNodeID profile;
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h Thu Jul 10 17:03:41 2008
@@ -61,14 +61,14 @@
/// number of times different CFGBlocks have been visited along a path.
GRBlockCounter::Factory BCounterFactory;
- void GenerateNode(const ProgramPoint& Loc, void* State,
+ void GenerateNode(const ProgramPoint& Loc, const void* State,
ExplodedNodeImpl* Pred = NULL);
/// getInitialState - Gets the void* representing the initial 'state'
/// of the analysis. This is simply a wrapper (implemented
/// in GRCoreEngine) that performs type erasure on the initial
/// state returned by the checker object.
- virtual void* getInitialState() = 0;
+ virtual const void* getInitialState() = 0;
void HandleBlockEdge(const BlockEdge& E, ExplodedNodeImpl* Pred);
void HandleBlockEntrance(const BlockEntrance& E, ExplodedNodeImpl* Pred);
@@ -81,7 +81,7 @@
virtual void ProcessEndPath(GREndPathNodeBuilderImpl& Builder) = 0;
- virtual bool ProcessBlockEntrance(CFGBlock* Blk, void* State,
+ virtual bool ProcessBlockEntrance(CFGBlock* Blk, const void* State,
GRBlockCounter BC) = 0;
virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0;
@@ -142,11 +142,11 @@
}
ExplodedNodeImpl*
- generateNodeImpl(Stmt* S, void* State, ExplodedNodeImpl* Pred,
+ generateNodeImpl(Stmt* S, const void* State, ExplodedNodeImpl* Pred,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind);
ExplodedNodeImpl*
- generateNodeImpl(Stmt* S, void* State,
+ generateNodeImpl(Stmt* S, const void* State,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
ExplodedNodeImpl* N = getLastNode();
assert (N && "Predecessor of new node is infeasible.");
@@ -169,7 +169,7 @@
typedef ExplodedNode<StateTy> NodeTy;
GRStmtNodeBuilderImpl& NB;
- StateTy* CleanedState;
+ const StateTy* CleanedState;
GRAuditor<StateTy> **CallExprAuditBeg, **CallExprAuditEnd;
GRAuditor<StateTy> **ObjCMsgExprAuditBeg, **ObjCMsgExprAuditEnd;
@@ -201,7 +201,7 @@
}
NodeTy*
- generateNode(Stmt* S, StateTy* St, NodeTy* Pred,
+ generateNode(Stmt* S, const StateTy* St, NodeTy* Pred,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
HasGeneratedNode = true;
@@ -210,7 +210,7 @@
}
NodeTy*
- generateNode(Stmt* S, StateTy* St,
+ generateNode(Stmt* S, const StateTy* St,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind) {
HasGeneratedNode = true;
@@ -226,21 +226,21 @@
return NB.getCurrentBlockCount();
}
- StateTy* GetState(NodeTy* Pred) const {
+ const StateTy* GetState(NodeTy* Pred) const {
if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
return CleanedState;
else
return Pred->getState();
}
- void SetCleanedState(StateTy* St) {
+ void SetCleanedState(const StateTy* St) {
CleanedState = St;
}
NodeTy* MakeNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
- NodeTy* Pred, StateTy* St) {
+ NodeTy* Pred, const StateTy* St) {
- StateTy* PredState = GetState(Pred);
+ const StateTy* PredState = GetState(Pred);
GRAuditor<StateTy> **AB = NULL, **AE = NULL;
@@ -309,7 +309,7 @@
const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
- ExplodedNodeImpl* generateNodeImpl(void* State, bool branch);
+ ExplodedNodeImpl* generateNodeImpl(const void* State, bool branch);
CFGBlock* getTargetBlock(bool branch) const {
return branch ? DstT : DstF;
@@ -340,11 +340,11 @@
return static_cast<NodeTy*>(NB.getPredecessor());
}
- StateTy* getState() const {
+ const StateTy* getState() const {
return getPredecessor()->getState();
}
- NodeTy* generateNode(StateTy* St, bool branch) {
+ NodeTy* generateNode(const StateTy* St, bool branch) {
return static_cast<NodeTy*>(NB.generateNodeImpl(St, branch));
}
@@ -396,11 +396,11 @@
Iterator begin() { return Iterator(DispatchBlock.succ_begin()); }
Iterator end() { return Iterator(DispatchBlock.succ_end()); }
- ExplodedNodeImpl* generateNodeImpl(const Iterator& I, void* State,
+ ExplodedNodeImpl* generateNodeImpl(const Iterator& I, const void* State,
bool isSink);
Expr* getTarget() const { return E; }
- void* getState() const { return Pred->State; }
+ const void* getState() const { return Pred->State; }
};
template<typename STATE>
@@ -421,12 +421,12 @@
Expr* getTarget() const { return NB.getTarget(); }
- NodeTy* generateNode(const iterator& I, StateTy* St, bool isSink=false){
+ NodeTy* generateNode(const iterator& I, const StateTy* St, bool isSink=false){
return static_cast<NodeTy*>(NB.generateNodeImpl(I, St, isSink));
}
- StateTy* getState() const {
- return static_cast<StateTy*>(NB.getState());
+ const StateTy* getState() const {
+ return static_cast<const StateTy*>(NB.getState());
}
};
@@ -462,11 +462,14 @@
Iterator begin() { return Iterator(Src->succ_rbegin()+1); }
Iterator end() { return Iterator(Src->succ_rend()); }
- ExplodedNodeImpl* generateCaseStmtNodeImpl(const Iterator& I, void* State);
- ExplodedNodeImpl* generateDefaultCaseNodeImpl(void* State, bool isSink);
+ ExplodedNodeImpl* generateCaseStmtNodeImpl(const Iterator& I,
+ const void* State);
+
+ ExplodedNodeImpl* generateDefaultCaseNodeImpl(const void* State,
+ bool isSink);
Expr* getCondition() const { return Condition; }
- void* getState() const { return Pred->State; }
+ const void* getState() const { return Pred->State; }
};
template<typename STATE>
@@ -487,16 +490,16 @@
Expr* getCondition() const { return NB.getCondition(); }
- NodeTy* generateCaseStmtNode(const iterator& I, StateTy* St) {
+ NodeTy* generateCaseStmtNode(const iterator& I, const StateTy* St) {
return static_cast<NodeTy*>(NB.generateCaseStmtNodeImpl(I, St));
}
- NodeTy* generateDefaultCaseNode(StateTy* St, bool isSink = false) {
+ NodeTy* generateDefaultCaseNode(const StateTy* St, bool isSink = false) {
return static_cast<NodeTy*>(NB.generateDefaultCaseNodeImpl(St, isSink));
}
- StateTy* getState() const {
- return static_cast<StateTy*>(NB.getState());
+ const StateTy* getState() const {
+ return static_cast<const StateTy*>(NB.getState());
}
};
@@ -522,7 +525,7 @@
return getBlockCounter().getNumVisited(B.getBlockID());
}
- ExplodedNodeImpl* generateNodeImpl(void* State);
+ ExplodedNodeImpl* generateNodeImpl(const void* State);
CFGBlock* getBlock() const { return &B; }
};
@@ -550,11 +553,11 @@
return NB.getCurrentBlockCount();
}
- StateTy* getState() const {
+ const StateTy* getState() const {
return getPredecessor()->getState();
}
- NodeTy* MakeNode(StateTy* St) {
+ NodeTy* MakeNode(const StateTy* St) {
return static_cast<NodeTy*>(NB.generateNodeImpl(St));
}
};
@@ -571,7 +574,7 @@
protected:
SubEngineTy& SubEngine;
- virtual void* getInitialState() {
+ virtual const void* getInitialState() {
return SubEngine.getInitialState();
}
@@ -585,9 +588,11 @@
SubEngine.ProcessStmt(S, Builder);
}
- virtual bool ProcessBlockEntrance(CFGBlock* Blk, void* State,
+ virtual bool ProcessBlockEntrance(CFGBlock* Blk, const void* State,
GRBlockCounter BC) {
- return SubEngine.ProcessBlockEntrance(Blk, static_cast<StateTy*>(State),BC);
+ return SubEngine.ProcessBlockEntrance(Blk,
+ static_cast<const StateTy*>(State),
+ BC);
}
virtual void ProcessBranch(Expr* Condition, Stmt* Terminator,
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Thu Jul 10 17:03:41 2008
@@ -86,7 +86,7 @@
/// CleanedState - The state for EntryNode "cleaned" of all dead
/// variables and symbols (as determined by a liveness analysis).
- ValueState* CleanedState;
+ const ValueState* CleanedState;
/// CurrentStmt - The current block-level statement.
Stmt* CurrentStmt;
@@ -210,7 +210,7 @@
/// getInitialState - Return the initial state used for the root vertex
/// in the ExplodedGraph.
- ValueState* getInitialState();
+ const ValueState* getInitialState();
GraphTy& getGraph() { return G; }
const GraphTy& getGraph() const { return G; }
@@ -370,7 +370,8 @@
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue
/// exploring the given path, and false otherwise.
- bool ProcessBlockEntrance(CFGBlock* B, ValueState* St, GRBlockCounter BC);
+ bool ProcessBlockEntrance(CFGBlock* B, const ValueState* St,
+ GRBlockCounter BC);
/// ProcessBranch - Called by GRCoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
@@ -401,7 +402,7 @@
protected:
- ValueState* GetState(NodeTy* N) {
+ const ValueState* GetState(NodeTy* N) {
return N == EntryNode ? CleanedState : N->getState();
}
@@ -409,35 +410,35 @@
// FIXME: Maybe make these accesible only within the StmtBuilder?
- ValueState* SetRVal(ValueState* St, Expr* Ex, RVal V);
+ const ValueState* SetRVal(const ValueState* St, Expr* Ex, RVal V);
- ValueState* SetRVal(ValueState* St, const Expr* Ex, RVal V) {
+ const ValueState* SetRVal(const ValueState* St, const Expr* Ex, RVal V) {
return SetRVal(St, const_cast<Expr*>(Ex), V);
}
protected:
- ValueState* SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V) {
+ const ValueState* SetBlkExprRVal(const ValueState* St, Expr* Ex, RVal V) {
return StateMgr.SetRVal(St, Ex, V, true, false);
}
- ValueState* SetRVal(ValueState* St, LVal LV, RVal V) {
+ const ValueState* SetRVal(const ValueState* St, LVal LV, RVal V) {
return StateMgr.SetRVal(St, LV, V);
}
- RVal GetRVal(ValueState* St, Expr* Ex) {
+ RVal GetRVal(const ValueState* St, Expr* Ex) {
return StateMgr.GetRVal(St, Ex);
}
- RVal GetRVal(ValueState* St, const Expr* Ex) {
+ RVal GetRVal(const ValueState* St, const Expr* Ex) {
return GetRVal(St, const_cast<Expr*>(Ex));
}
- RVal GetBlkExprRVal(ValueState* St, Expr* Ex) {
+ RVal GetBlkExprRVal(const ValueState* St, Expr* Ex) {
return StateMgr.GetBlkExprRVal(St, Ex);
}
- RVal GetRVal(ValueState* St, LVal LV, QualType T = QualType()) {
+ RVal GetRVal(const ValueState* St, LVal LV, QualType T = QualType()) {
return StateMgr.GetRVal(St, LV, T);
}
@@ -447,8 +448,8 @@
/// Assume - Create new state by assuming that a given expression
/// is true or false.
- ValueState* Assume(ValueState* St, RVal Cond, bool Assumption,
- bool& isFeasible) {
+ const ValueState* Assume(const ValueState* St, RVal Cond, bool Assumption,
+ bool& isFeasible) {
if (Cond.isUnknown()) {
isFeasible = true;
@@ -461,28 +462,28 @@
return Assume(St, cast<NonLVal>(Cond), Assumption, isFeasible);
}
- ValueState* Assume(ValueState* St, LVal Cond, bool Assumption,
- bool& isFeasible);
+ const ValueState* Assume(const ValueState* St, LVal Cond, bool Assumption,
+ bool& isFeasible);
- ValueState* AssumeAux(ValueState* St, LVal Cond, bool Assumption,
- bool& isFeasible);
+ const ValueState* AssumeAux(const ValueState* St, LVal Cond, bool Assumption,
+ bool& isFeasible);
- ValueState* Assume(ValueState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible);
+ const ValueState* Assume(const ValueState* St, NonLVal Cond, bool Assumption,
+ bool& isFeasible);
- ValueState* AssumeAux(ValueState* St, NonLVal Cond, bool Assumption,
- bool& isFeasible);
+ const ValueState* AssumeAux(const ValueState* St, NonLVal Cond,
+ bool Assumption, bool& isFeasible);
- ValueState* AssumeSymNE(ValueState* St, SymbolID sym, const llvm::APSInt& V,
- bool& isFeasible);
+ const ValueState* AssumeSymNE(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V, bool& isFeasible);
- ValueState* AssumeSymEQ(ValueState* St, SymbolID sym, const llvm::APSInt& V,
- bool& isFeasible);
+ const ValueState* AssumeSymEQ(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V, bool& isFeasible);
- ValueState* AssumeSymInt(ValueState* St, bool Assumption,
- const SymIntConstraint& C, bool& isFeasible);
+ const ValueState* AssumeSymInt(const ValueState* St, bool Assumption,
+ const SymIntConstraint& C, bool& isFeasible);
- NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, ValueState* St) {
+ NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const ValueState* St) {
assert (Builder && "GRStmtNodeBuilder not present.");
return Builder->MakeNode(Dst, S, Pred, St);
}
@@ -568,7 +569,8 @@
void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst,
bool asLVal);
- bool CheckDivideZero(Expr* Ex, ValueState* St, NodeTy* Pred, RVal Denom);
+ bool CheckDivideZero(Expr* Ex, const ValueState* St, NodeTy* Pred,
+ RVal Denom);
RVal EvalCast(RVal X, QualType CastT) {
if (X.isUnknownOrUndef())
@@ -634,21 +636,22 @@
TF->EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
}
- void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St,
+ void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, const ValueState* St,
RVal TargetLV, RVal Val);
// FIXME: The "CheckOnly" option exists only because Array and Field
// loads aren't fully implemented. Eventually this option will go away.
void EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
- ValueState* St, RVal location, bool CheckOnly = false);
+ const ValueState* St, RVal location, bool CheckOnly = false);
- ValueState* EvalLocation(Expr* Ex, NodeTy* Pred,
- ValueState* St, RVal location, bool isLoad = false);
+ const ValueState* EvalLocation(Expr* Ex, NodeTy* Pred,
+ const ValueState* St, RVal location,
+ bool isLoad = false);
void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred);
- ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken);
+ const ValueState* MarkBranch(const ValueState* St, Stmt* Terminator, bool branchTaken);
};
} // end clang namespace
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Thu Jul 10 17:03:41 2008
@@ -82,7 +82,7 @@
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 and dead symbol notification.
@@ -96,7 +96,7 @@
GRStmtNodeBuilder<ValueState>& Builder,
ExplodedNode<ValueState>* Pred,
Stmt* S,
- ValueState* St,
+ const ValueState* St,
const ValueStateManager::DeadSymbolsTy& Dead) {}
// Return statements.
@@ -109,8 +109,10 @@
// 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) {
return St;
}
};
Added: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=53423&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (added)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Thu Jul 10 17:03:41 2008
@@ -0,0 +1,34 @@
+//== Store.h - Interface for maps 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 types Store and StoreManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_STORE_H
+#define LLVM_CLANG_ANALYSIS_STORE_H
+
+#include "clang/Analysis/PathSensitive/RValues.h"
+
+namespace clang {
+
+typedef const void* Store;
+
+class StoreManager {
+public:
+ virtual ~StoreManager() {}
+ virtual RVal GetRVal(Store St, LVal LV, QualType T) = 0;
+ virtual Store SetRVal(Store St, LVal LV, RVal V) = 0;
+ virtual Store Remove(Store St, LVal LV) = 0;
+ virtual Store getInitialStore() = 0;
+};
+
+} // end clang namespace
+
+#endif
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h Thu Jul 10 17:03:41 2008
@@ -17,6 +17,7 @@
// FIXME: Reduce the number of includes.
#include "clang/Analysis/PathSensitive/Environment.h"
+#include "clang/Analysis/PathSensitive/Store.h"
#include "clang/Analysis/PathSensitive/RValues.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/AST/Expr.h"
@@ -54,7 +55,6 @@
public:
// Typedefs.
typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
- typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
typedef llvm::ImmutableMap<SymbolID,IntSetTy> ConstNotEqTy;
typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
@@ -64,10 +64,10 @@
friend class ValueStateManager;
Environment Env;
+ Store St;
// FIXME: Make these private.
public:
- VarBindingsTy VarBindings;
ConstNotEqTy ConstNotEq;
ConstEqTy ConstEq;
void* CheckerState;
@@ -75,10 +75,10 @@
public:
/// This ctor is used when creating the first ValueState object.
- ValueState(const Environment& env, VarBindingsTy VB,
+ ValueState(const Environment& env, Store st,
ConstNotEqTy CNE, ConstEqTy CE)
: Env(env),
- VarBindings(VB),
+ St(st),
ConstNotEq(CNE),
ConstEq(CE),
CheckerState(NULL) {}
@@ -88,7 +88,7 @@
ValueState(const ValueState& RHS)
: llvm::FoldingSetNode(),
Env(RHS.Env),
- VarBindings(RHS.VarBindings),
+ St(RHS.St),
ConstNotEq(RHS.ConstNotEq),
ConstEq(RHS.ConstEq),
CheckerState(RHS.CheckerState) {}
@@ -97,11 +97,15 @@
/// The environment is the mapping from expressions to values.
const Environment& getEnvironment() const { return Env; }
+ /// getStore - Return the store associated with this state. The store
+ /// is a mapping from locations to values.
+ Store getStore() const { return St; }
+
/// Profile - Profile the contents of a ValueState object for use
/// in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID& ID, const ValueState* V) {
V->Env.Profile(ID);
- V->VarBindings.Profile(ID);
+ ID.AddPointer(V->St);
V->ConstNotEq.Profile(ID);
V->ConstEq.Profile(ID);
ID.AddPointer(V->CheckerState);
@@ -124,9 +128,18 @@
// Iterators.
+ // FIXME: We'll be removing the VarBindings iterator very soon. Right now
+ // it assumes that Store is a VarBindingsTy.
+ typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
typedef VarBindingsTy::iterator vb_iterator;
- vb_iterator vb_begin() const { return VarBindings.begin(); }
- vb_iterator vb_end() const { return VarBindings.end(); }
+ vb_iterator vb_begin() const {
+ VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+ return B.begin();
+ }
+ vb_iterator vb_end() const {
+ VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+ return B.end();
+ }
typedef Environment::seb_iterator seb_iterator;
seb_iterator seb_begin() const { return Env.seb_begin(); }
@@ -173,8 +186,8 @@
class ValueStateManager {
private:
EnvironmentManager EnvMgr;
+ llvm::OwningPtr<StoreManager> StMgr;
ValueState::IntSetTy::Factory ISetFactory;
- ValueState::VarBindingsTy::Factory VBFactory;
ValueState::ConstNotEqTy::Factory CNEFactory;
ValueState::ConstEqTy::Factory CEFactory;
@@ -196,58 +209,53 @@
Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
return EnvMgr.RemoveBlkExpr(Env, E);
}
-
- ValueState::VarBindingsTy Remove(ValueState::VarBindingsTy B, VarDecl* V) {
- return VBFactory.Remove(B, V);
- }
-
- ValueState::VarBindingsTy Remove(const ValueState& V, VarDecl* D) {
- return Remove(V.VarBindings, D);
+
+ // FIXME: Remove when we do lazy initializaton of variable bindings.
+ const ValueState* BindVar(const ValueState* St, VarDecl* D, RVal V) {
+ return SetRVal(St, lval::DeclVal(D), V);
}
-
- ValueState* BindVar(ValueState* St, VarDecl* D, RVal V);
- ValueState* UnbindVar(ValueState* St, VarDecl* D);
-
+
public:
- ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& alloc)
- : EnvMgr(alloc),
- ISetFactory(alloc),
- VBFactory(alloc),
- CNEFactory(alloc),
- CEFactory(alloc),
- BasicVals(Ctx, alloc),
- SymMgr(alloc),
- Alloc(alloc) {}
-
- ValueState* getInitialState();
+ ValueStateManager(ASTContext& Ctx, StoreManager* stmgr,
+ llvm::BumpPtrAllocator& alloc)
+ : EnvMgr(alloc),
+ StMgr(stmgr),
+ ISetFactory(alloc),
+ CNEFactory(alloc),
+ CEFactory(alloc),
+ BasicVals(Ctx, alloc),
+ SymMgr(alloc),
+ Alloc(alloc) {}
+
+ const ValueState* getInitialState();
BasicValueFactory& getBasicValueFactory() { return BasicVals; }
SymbolManager& getSymbolManager() { return SymMgr; }
typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
- ValueState* RemoveDeadBindings(ValueState* St, Stmt* Loc,
- const LiveVariables& Liveness,
- DeadSymbolsTy& DeadSymbols);
+ const ValueState* RemoveDeadBindings(const ValueState* St, Stmt* Loc,
+ const LiveVariables& Liveness,
+ DeadSymbolsTy& DeadSymbols);
- ValueState* RemoveSubExprBindings(ValueState* St) {
+ const ValueState* RemoveSubExprBindings(const ValueState* St) {
ValueState NewSt = *St;
NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
- return getPersistentState(NewSt);
+ return getPersistentState(NewSt);
}
// Methods that query & manipulate the Environment.
- RVal GetRVal(ValueState* St, Expr* Ex) {
+ RVal GetRVal(const ValueState* St, Expr* Ex) {
return St->getEnvironment().GetRVal(Ex, BasicVals);
}
- RVal GetBlkExprRVal(ValueState* St, Expr* Ex) {
+ RVal GetBlkExprRVal(const ValueState* St, Expr* Ex) {
return St->getEnvironment().GetBlkExprRVal(Ex, BasicVals);
}
- ValueState* SetRVal(ValueState* St, Expr* Ex, RVal V, bool isBlkExpr,
- bool Invalidate) {
+ const ValueState* SetRVal(const ValueState* St, Expr* Ex, RVal V,
+ bool isBlkExpr, bool Invalidate) {
const Environment& OldEnv = St->getEnvironment();
Environment NewEnv = EnvMgr.SetRVal(OldEnv, Ex, V, isBlkExpr, Invalidate);
@@ -262,18 +270,29 @@
// Methods that query & manipulate the Store.
- RVal GetRVal(ValueState* St, LVal LV, QualType T = QualType());
+ RVal GetRVal(const ValueState* St, LVal LV, QualType T = QualType()) {
+ return StMgr->GetRVal(St->getStore(), LV, T);
+ }
- ValueState* SetRVal(ValueState* St, LVal LV, RVal V);
+ void SetRVal(ValueState& St, LVal LV, RVal V) {
+ St.St = StMgr->SetRVal(St.St, LV, V);
+ }
+
+ const ValueState* SetRVal(const ValueState* St, LVal LV, RVal V);
- void BindVar(ValueState& StImpl, VarDecl* D, RVal V);
+ void Unbind(ValueState& St, LVal LV) {
+ St.St = StMgr->Remove(St.St, LV);
+ }
- void Unbind(ValueState& StImpl, LVal LV);
+ const ValueState* Unbind(const ValueState* St, LVal LV);
- ValueState* getPersistentState(ValueState& Impl);
+ const ValueState* getPersistentState(ValueState& Impl);
- ValueState* AddEQ(ValueState* St, SymbolID sym, const llvm::APSInt& V);
- ValueState* AddNE(ValueState* St, SymbolID sym, const llvm::APSInt& V);
+ const ValueState* AddEQ(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V);
+
+ const ValueState* AddNE(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V);
};
} // end clang namespace
Modified: cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicObjCFoundationChecks.cpp Thu Jul 10 17:03:41 2008
@@ -107,7 +107,7 @@
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 @@
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:
Added: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=53423&view=auto
==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (added)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Thu Jul 10 17:03:41 2008
@@ -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;
+ }
+}
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Thu Jul 10 17:03:41 2008
@@ -327,7 +327,7 @@
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 @@
// 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 @@
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.
Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Thu Jul 10 17:03:41 2008
@@ -1135,8 +1135,8 @@
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 @@
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 @@
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 @@
GRStmtNodeBuilder<ValueState>& Builder,
ExplodedNode<ValueState>* Pred,
Stmt* S,
- ValueState* St,
+ const ValueState* St,
const ValueStateManager::DeadSymbolsTy& Dead);
// Return statements.
@@ -1249,8 +1250,9 @@
// 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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
}
-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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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))
Modified: cfe/trunk/lib/Analysis/GRCoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRCoreEngine.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRCoreEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRCoreEngine.cpp Thu Jul 10 17:03:41 2008
@@ -255,8 +255,8 @@
/// 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 @@
}
ExplodedNodeImpl*
-GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, void* State,
+GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, const void* State,
ExplodedNodeImpl* Pred,
ProgramPoint::Kind K) {
@@ -342,7 +342,7 @@
return NULL;
}
-ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State,
+ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
bool branch) {
bool IsNew;
@@ -374,7 +374,7 @@
ExplodedNodeImpl*
GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
- void* St,
+ const void* St,
bool isSink) {
bool IsNew;
@@ -399,7 +399,8 @@
ExplodedNodeImpl*
-GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, void* St) {
+GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
+ const void* St) {
bool IsNew;
@@ -418,7 +419,8 @@
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 @@
if (!HasGeneratedNode) generateNodeImpl(Pred->State);
}
-ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(void* State) {
+ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(const void* State){
HasGeneratedNode = true;
bool IsNew;
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Jul 10 17:03:41 2008
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
// 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 @@
/// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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::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 @@
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 @@
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 @@
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::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::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 @@
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 @@
// "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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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->begin_outputs(),
OE = A->end_outputs(); OI != OE; ++OI) {
@@ -1949,7 +1956,7 @@
// Transfer functions: Binary operators.
//===----------------------------------------------------------------------===//
-bool GRExprEngine::CheckDivideZero(Expr* Ex, ValueState* St,
+bool GRExprEngine::CheckDivideZero(Expr* Ex, const ValueState* St,
NodeTy* Pred, RVal Denom) {
// Divide by undefined? (potentially zero)
@@ -1969,7 +1976,7 @@
// First, "assume" that the denominator is 0 or undefined.
bool isFeasibleZero = false;
- ValueState* ZeroSt = Assume(St, Denom, false, isFeasibleZero);
+ const ValueState* ZeroSt = Assume(St, Denom, false, isFeasibleZero);
// Second, "assume" that the denominator cannot be 0.
@@ -2018,7 +2025,7 @@
for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
- ValueState* St = GetState(*I2);
+ const ValueState* St = GetState(*I2);
RVal RightV = GetRVal(St, RHS);
BinaryOperator::Opcode Op = B->getOpcode();
@@ -2175,8 +2182,8 @@
// "Assume" logic.
//===----------------------------------------------------------------------===//
-ValueState* GRExprEngine::Assume(ValueState* St, LVal Cond,
- bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::Assume(const ValueState* St, LVal Cond,
+ bool Assumption, bool& isFeasible) {
St = AssumeAux(St, Cond, Assumption, isFeasible);
@@ -2184,8 +2191,8 @@
: St;
}
-ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
- bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeAux(const ValueState* St, LVal Cond,
+ bool Assumption, bool& isFeasible) {
switch (Cond.getSubKind()) {
default:
@@ -2224,8 +2231,8 @@
}
}
-ValueState* GRExprEngine::Assume(ValueState* St, NonLVal Cond,
- bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::Assume(const ValueState* St, NonLVal Cond,
+ bool Assumption, bool& isFeasible) {
St = AssumeAux(St, Cond, Assumption, isFeasible);
@@ -2233,8 +2240,8 @@
: St;
}
-ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond,
- bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeAux(const ValueState* St, NonLVal Cond,
+ bool Assumption, bool& isFeasible) {
switch (Cond.getSubKind()) {
default:
assert (false && "'Assume' not implemented for this NonLVal.");
@@ -2272,9 +2279,9 @@
}
}
-ValueState*
-GRExprEngine::AssumeSymNE(ValueState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeSymNE(const ValueState* St,
+ SymbolID sym, const llvm::APSInt& V,
+ bool& isFeasible) {
// First, determine if sym == X, where X != V.
if (const llvm::APSInt* X = St->getSymVal(sym)) {
@@ -2295,9 +2302,8 @@
return StateMgr.AddNE(St, sym, V);
}
-ValueState*
-GRExprEngine::AssumeSymEQ(ValueState* St, SymbolID sym,
- const llvm::APSInt& V, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeSymEQ(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V, bool& isFeasible) {
// First, determine if sym == X, where X != V.
if (const llvm::APSInt* X = St->getSymVal(sym)) {
@@ -2318,9 +2324,10 @@
return StateMgr.AddEQ(St, sym, V);
}
-ValueState*
-GRExprEngine::AssumeSymInt(ValueState* St, bool Assumption,
- const SymIntConstraint& C, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeSymInt(const ValueState* St,
+ bool Assumption,
+ const SymIntConstraint& C,
+ bool& isFeasible) {
switch (C.getOpcode()) {
default:
Modified: cfe/trunk/lib/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRSimpleVals.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Thu Jul 10 17:03:41 2008
@@ -265,9 +265,9 @@
struct VISIBILITY_HIDDEN FindUndefExpr {
ValueStateManager& VM;
- ValueState* St;
+ const ValueState* St;
- FindUndefExpr(ValueStateManager& V, ValueState* S) : VM(V), St(S) {}
+ FindUndefExpr(ValueStateManager& V, const ValueState* S) : VM(V), St(S) {}
Expr* FindExpr(Expr* Ex) {
@@ -319,7 +319,7 @@
ExplodedNode<ValueState> *N = *(*I)->pred_begin();
ProgramPoint P = N->getLocation();
- ValueState* St = (*I)->getState();
+ const ValueState* St = (*I)->getState();
if (PostStmt* PS = dyn_cast<PostStmt>(&P))
if (PS->getStmt() == Ex)
@@ -652,7 +652,7 @@
ExplodedNode<ValueState>* Pred) {
ValueStateManager& StateMgr = Eng.getStateManager();
- ValueState* St = Builder.GetState(Pred);
+ const ValueState* St = Builder.GetState(Pred);
// Invalidate all arguments passed in by reference (LVals).
@@ -700,7 +700,7 @@
// We just invalidate all arguments passed in by references.
ValueStateManager& StateMgr = Eng.getStateManager();
- ValueState* St = Builder.GetState(Pred);
+ const ValueState* St = Builder.GetState(Pred);
for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
I != E; ++I) {
Modified: cfe/trunk/lib/Analysis/GRTransferFuncs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRTransferFuncs.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRTransferFuncs.cpp (original)
+++ cfe/trunk/lib/Analysis/GRTransferFuncs.cpp Thu Jul 10 17:03:41 2008
@@ -23,7 +23,7 @@
GRExprEngine& Eng,
GRStmtNodeBuilder<ValueState>& Builder,
Expr* E, ExplodedNode<ValueState>* Pred,
- ValueState* St, RVal TargetLV, RVal Val) {
+ const ValueState* St, RVal TargetLV, RVal Val) {
// This code basically matches the "safety-net" logic of GRExprEngine:
// bind Val to TargetLV, and create a new node. We replicate it here
Modified: cfe/trunk/lib/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ValueState.cpp?rev=53423&r1=53422&r2=53423&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ValueState.cpp (original)
+++ cfe/trunk/lib/Analysis/ValueState.cpp Thu Jul 10 17:03:41 2008
@@ -30,8 +30,8 @@
return T ? *T : NULL;
}
-ValueState*
-ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
+const ValueState*
+ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc,
const LiveVariables& Liveness,
DeadSymbolsTy& DeadSymbols) {
@@ -126,7 +126,7 @@
for (ValueState::vb_iterator I = St->vb_begin(), E = St->vb_end(); I!=E ; ++I)
if (!Marked.count(I.getKey())) {
- NewSt.VarBindings = Remove(NewSt, I.getKey());
+ NewSt.St = StMgr->Remove(NewSt.St, lval::DeclVal(I.getKey()));
RVal X = I.getData();
@@ -160,77 +160,35 @@
return getPersistentState(NewSt);
}
-
-RVal ValueStateManager::GetRVal(ValueState* St, LVal LV, QualType T) {
+const ValueState* ValueStateManager::SetRVal(const ValueState* St, LVal LV,
+ RVal V) {
- if (isa<UnknownVal>(LV))
- return UnknownVal();
+ Store OldStore = St->getStore();
+ Store NewStore = StMgr->SetRVal(OldStore, LV, V);
- assert (!isa<UndefinedVal>(LV));
+ if (NewStore == OldStore)
+ return St;
- switch (LV.getSubKind()) {
- case lval::DeclValKind: {
- ValueState::VarBindingsTy::data_type* T =
- St->VarBindings.lookup(cast<lval::DeclVal>(LV).getDecl());
-
- return T ? *T : UnknownVal();
- }
-
- // FIXME: We should limit how far a "ContentsOf" will go...
-
- 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();
+ ValueState NewSt = *St;
+ NewSt.St = NewStore;
+ return getPersistentState(NewSt);
+}
- 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;
- }
+const ValueState* ValueStateManager::Unbind(const ValueState* St, LVal LV) {
+ Store OldStore = St->getStore();
+ Store NewStore = StMgr->Remove(OldStore, LV);
- return UnknownVal();
+ if (NewStore == OldStore)
+ return St;
+
+ ValueState NewSt = *St;
+ NewSt.St = NewStore;
+ return getPersistentState(NewSt);
}
-ValueState* ValueStateManager::AddNE(ValueState* St, SymbolID sym,
- const llvm::APSInt& V) {
+
+const ValueState* ValueStateManager::AddNE(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V) {
// First, retrieve the NE-set associated with the given symbol.
ValueState::ConstNotEqTy::data_type* T = St->ConstNotEq.lookup(sym);
@@ -247,8 +205,8 @@
return getPersistentState(NewSt);
}
-ValueState* ValueStateManager::AddEQ(ValueState* St, SymbolID sym,
- const llvm::APSInt& V) {
+const ValueState* ValueStateManager::AddEQ(const ValueState* St, SymbolID sym,
+ const llvm::APSInt& V) {
// Create a new state with the old binding replaced.
ValueState NewSt = *St;
@@ -258,66 +216,17 @@
return getPersistentState(NewSt);
}
+const ValueState* ValueStateManager::getInitialState() {
-ValueState* ValueStateManager::SetRVal(ValueState* St, LVal LV, RVal V) {
-
- switch (LV.getSubKind()) {
-
- case lval::DeclValKind:
- return V.isUnknown()
- ? UnbindVar(St, cast<lval::DeclVal>(LV).getDecl())
- : BindVar(St, cast<lval::DeclVal>(LV).getDecl(), V);
-
- default:
- assert ("SetRVal for given LVal type not yet implemented.");
- return St;
- }
-}
-
-void ValueStateManager::BindVar(ValueState& StImpl, VarDecl* D, RVal V) {
- StImpl.VarBindings = VBFactory.Add(StImpl.VarBindings, D, V);
-}
-
-ValueState* ValueStateManager::BindVar(ValueState* St, VarDecl* D, RVal V) {
-
- // Create a new state with the old binding removed.
- ValueState NewSt = *St;
- NewSt.VarBindings = VBFactory.Add(NewSt.VarBindings, D, V);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
-}
-
-ValueState* ValueStateManager::UnbindVar(ValueState* St, VarDecl* D) {
-
- // Create a new state with the old binding removed.
- ValueState NewSt = *St;
- NewSt.VarBindings = VBFactory.Remove(NewSt.VarBindings, D);
-
- // Get the persistent copy.
- return getPersistentState(NewSt);
-}
-
-void ValueStateManager::Unbind(ValueState& StImpl, LVal LV) {
-
- if (isa<lval::DeclVal>(LV))
- StImpl.VarBindings = VBFactory.Remove(StImpl.VarBindings,
- cast<lval::DeclVal>(LV).getDecl());
-
-}
-
-ValueState* ValueStateManager::getInitialState() {
-
- // Create a state with empty variable bindings.
ValueState StateImpl(EnvMgr.getInitialEnvironment(),
- VBFactory.GetEmptyMap(),
+ StMgr->getInitialStore(),
CNEFactory.GetEmptyMap(),
CEFactory.GetEmptyMap());
return getPersistentState(StateImpl);
}
-ValueState* ValueStateManager::getPersistentState(ValueState& State) {
+const ValueState* ValueStateManager::getPersistentState(ValueState& State) {
llvm::FoldingSetNodeID ID;
State.Profile(ID);
More information about the cfe-commits
mailing list