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:
parent
b3ca38c1d5
commit
d5804b31c4
|
@ -549,7 +549,13 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Dispatch to the plug-in transfer function.
|
// 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.
|
// Check for the "noreturn" attribute.
|
||||||
|
|
|
@ -397,9 +397,14 @@ RVal GRSimpleVals::EvalNE(ValueManager& ValMgr, LVal L, LVal R) {
|
||||||
// Transfer function for Function Calls.
|
// Transfer function for Function Calls.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
ValueState*
|
void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
||||||
GRSimpleVals::EvalCall(ValueStateManager& StateMgr, ValueManager& ValMgr,
|
ValueStateManager& StateMgr,
|
||||||
CallExpr* CE, LVal L, ValueState* St) {
|
GRStmtNodeBuilder<ValueState>& Builder,
|
||||||
|
ValueManager& ValMgr,
|
||||||
|
CallExpr* CE, LVal L,
|
||||||
|
ExplodedNode<ValueState>* Pred) {
|
||||||
|
|
||||||
|
ValueState* St = Pred->getState();
|
||||||
|
|
||||||
// Invalidate all arguments passed in by reference (LVals).
|
// Invalidate all arguments passed in by reference (LVals).
|
||||||
|
|
||||||
|
@ -411,6 +416,6 @@ GRSimpleVals::EvalCall(ValueStateManager& StateMgr, ValueManager& ValMgr,
|
||||||
if (isa<LVal>(V))
|
if (isa<LVal>(V))
|
||||||
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
|
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
return St;
|
Builder.Nodify(Dst, CE, Pred, St);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,10 +52,12 @@ public:
|
||||||
|
|
||||||
// Calls.
|
// Calls.
|
||||||
|
|
||||||
virtual ValueState* EvalCall(ValueStateManager& StateMgr,
|
virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
||||||
ValueManager& ValMgr,
|
ValueStateManager& StateMgr,
|
||||||
CallExpr* CE, LVal L,
|
GRStmtNodeBuilder<ValueState>& Builder,
|
||||||
ValueState* St);
|
ValueManager& ValMgr,
|
||||||
|
CallExpr* CE, LVal L,
|
||||||
|
ExplodedNode<ValueState>* Pred);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -365,9 +365,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename NodeTy>
|
template <typename StateTy>
|
||||||
class ExplodedNodeSet {
|
class ExplodedNodeSet {
|
||||||
|
|
||||||
|
typedef ExplodedNode<StateTy> NodeTy;
|
||||||
typedef llvm::SmallPtrSet<NodeTy*,5> ImplTy;
|
typedef llvm::SmallPtrSet<NodeTy*,5> ImplTy;
|
||||||
ImplTy Impl;
|
ImplTy Impl;
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ public:
|
||||||
return static_cast<NodeTy*>(NB.generateNodeImpl(S, St));
|
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) {
|
NodeTy* Pred, StateTy* St) {
|
||||||
|
|
||||||
// If the state hasn't changed, don't generate a new node.
|
// If the state hasn't changed, don't generate a new node.
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
typedef GRBranchNodeBuilder<GRExprEngine> BranchNodeBuilder;
|
typedef GRBranchNodeBuilder<GRExprEngine> BranchNodeBuilder;
|
||||||
typedef GRIndirectGotoNodeBuilder<GRExprEngine> IndirectGotoNodeBuilder;
|
typedef GRIndirectGotoNodeBuilder<GRExprEngine> IndirectGotoNodeBuilder;
|
||||||
typedef GRSwitchNodeBuilder<GRExprEngine> SwitchNodeBuilder;
|
typedef GRSwitchNodeBuilder<GRExprEngine> SwitchNodeBuilder;
|
||||||
typedef ExplodedNodeSet<NodeTy> NodeSet;
|
typedef ExplodedNodeSet<StateTy> NodeSet;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// G - the simulation graph.
|
/// G - the simulation graph.
|
||||||
|
@ -414,8 +414,9 @@ protected:
|
||||||
return TF->EvalBinOp(ValMgr, Op, cast<NonLVal>(L), cast<NonLVal>(R));
|
return TF->EvalBinOp(ValMgr, Op, cast<NonLVal>(L), cast<NonLVal>(R));
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueState* EvalCall(CallExpr* CE, LVal L, ValueState* St) {
|
void EvalCall(NodeSet& Dst, CallExpr* CE, LVal L, NodeTy* Pred) {
|
||||||
return TF->EvalCall(StateMgr, ValMgr, CE, L, St);
|
assert (Builder && "GRStmtNodeBuilder must be defined.");
|
||||||
|
return TF->EvalCall(Dst, StateMgr, *Builder, ValMgr, CE, L, Pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken);
|
ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken);
|
||||||
|
|
|
@ -54,9 +54,11 @@ public:
|
||||||
|
|
||||||
// Calls.
|
// Calls.
|
||||||
|
|
||||||
virtual ValueState* EvalCall(ValueStateManager& StateMgr,
|
virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
||||||
ValueManager& ValMgr, CallExpr* CE, LVal L,
|
ValueStateManager& StateMgr,
|
||||||
ValueState* St) = 0;
|
GRStmtNodeBuilder<ValueState>& Builder,
|
||||||
|
ValueManager& ValMgr, CallExpr* CE, LVal L,
|
||||||
|
ExplodedNode<ValueState>* Pred) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end clang namespace
|
} // end clang namespace
|
||||||
|
|
Loading…
Reference in New Issue