Plug-in transfer function "EvalCall" now takes as an argument the current

GRStmtNodeBuilder and is now responsible for adding its own nodes to the graph.

llvm-svn: 47923
This commit is contained in:
Ted Kremenek 2008-03-05 00:33:14 +00:00
parent b3ca38c1d5
commit d5804b31c4
7 changed files with 35 additions and 18 deletions

View File

@ -549,7 +549,13 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
continue;
// Dispatch to the plug-in transfer function.
St = EvalCall(CE, cast<LVal>(L), (*DI)->getState());
unsigned size = Dst.size();
EvalCall(Dst, CE, cast<LVal>(L), *DI);
if (Dst.size() == size)
Nodify(Dst, CE, *DI, St);
}
// Check for the "noreturn" attribute.

View File

@ -397,9 +397,14 @@ RVal GRSimpleVals::EvalNE(ValueManager& ValMgr, LVal L, LVal R) {
// Transfer function for Function Calls.
//===----------------------------------------------------------------------===//
ValueState*
GRSimpleVals::EvalCall(ValueStateManager& StateMgr, ValueManager& ValMgr,
CallExpr* CE, LVal L, ValueState* St) {
void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
ValueStateManager& StateMgr,
GRStmtNodeBuilder<ValueState>& Builder,
ValueManager& ValMgr,
CallExpr* CE, LVal L,
ExplodedNode<ValueState>* Pred) {
ValueState* St = Pred->getState();
// Invalidate all arguments passed in by reference (LVals).
@ -411,6 +416,6 @@ GRSimpleVals::EvalCall(ValueStateManager& StateMgr, ValueManager& ValMgr,
if (isa<LVal>(V))
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
}
return St;
Builder.Nodify(Dst, CE, Pred, St);
}

View File

@ -52,10 +52,12 @@ public:
// Calls.
virtual ValueState* EvalCall(ValueStateManager& StateMgr,
ValueManager& ValMgr,
CallExpr* CE, LVal L,
ValueState* St);
virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
ValueStateManager& StateMgr,
GRStmtNodeBuilder<ValueState>& Builder,
ValueManager& ValMgr,
CallExpr* CE, LVal L,
ExplodedNode<ValueState>* Pred);
protected:

View File

@ -365,9 +365,10 @@ public:
};
template <typename NodeTy>
template <typename StateTy>
class ExplodedNodeSet {
typedef ExplodedNode<StateTy> NodeTy;
typedef llvm::SmallPtrSet<NodeTy*,5> ImplTy;
ImplTy Impl;

View File

@ -176,7 +176,7 @@ public:
return static_cast<NodeTy*>(NB.generateNodeImpl(S, St));
}
NodeTy* Nodify(ExplodedNodeSet<NodeTy>& Dst, Stmt* S,
NodeTy* Nodify(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
NodeTy* Pred, StateTy* St) {
// If the state hasn't changed, don't generate a new node.

View File

@ -31,7 +31,7 @@ public:
typedef GRBranchNodeBuilder<GRExprEngine> BranchNodeBuilder;
typedef GRIndirectGotoNodeBuilder<GRExprEngine> IndirectGotoNodeBuilder;
typedef GRSwitchNodeBuilder<GRExprEngine> SwitchNodeBuilder;
typedef ExplodedNodeSet<NodeTy> NodeSet;
typedef ExplodedNodeSet<StateTy> NodeSet;
protected:
/// G - the simulation graph.
@ -414,8 +414,9 @@ protected:
return TF->EvalBinOp(ValMgr, Op, cast<NonLVal>(L), cast<NonLVal>(R));
}
ValueState* EvalCall(CallExpr* CE, LVal L, ValueState* St) {
return TF->EvalCall(StateMgr, ValMgr, CE, L, St);
void EvalCall(NodeSet& Dst, CallExpr* CE, LVal L, NodeTy* Pred) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
return TF->EvalCall(Dst, StateMgr, *Builder, ValMgr, CE, L, Pred);
}
ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken);

View File

@ -54,9 +54,11 @@ public:
// Calls.
virtual ValueState* EvalCall(ValueStateManager& StateMgr,
ValueManager& ValMgr, CallExpr* CE, LVal L,
ValueState* St) = 0;
virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
ValueStateManager& StateMgr,
GRStmtNodeBuilder<ValueState>& Builder,
ValueManager& ValMgr, CallExpr* CE, LVal L,
ExplodedNode<ValueState>* Pred) = 0;
};
} // end clang namespace