diff --git a/clang/Analysis/GRExprEngine.cpp b/clang/Analysis/GRExprEngine.cpp index 61d10a4ecca1..2481f568386a 100644 --- a/clang/Analysis/GRExprEngine.cpp +++ b/clang/Analysis/GRExprEngine.cpp @@ -549,7 +549,13 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred, continue; // Dispatch to the plug-in transfer function. - St = EvalCall(CE, cast(L), (*DI)->getState()); + + unsigned size = Dst.size(); + + EvalCall(Dst, CE, cast(L), *DI); + + if (Dst.size() == size) + Nodify(Dst, CE, *DI, St); } // Check for the "noreturn" attribute. diff --git a/clang/Analysis/GRSimpleVals.cpp b/clang/Analysis/GRSimpleVals.cpp index fbaccba94f79..d8a3112b1a30 100644 --- a/clang/Analysis/GRSimpleVals.cpp +++ b/clang/Analysis/GRSimpleVals.cpp @@ -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& Dst, + ValueStateManager& StateMgr, + GRStmtNodeBuilder& Builder, + ValueManager& ValMgr, + CallExpr* CE, LVal L, + ExplodedNode* 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(V)) St = StateMgr.SetRVal(St, cast(V), UnknownVal()); } - - return St; + + Builder.Nodify(Dst, CE, Pred, St); } diff --git a/clang/Analysis/GRSimpleVals.h b/clang/Analysis/GRSimpleVals.h index 43fed85fdde8..c947afdb5762 100644 --- a/clang/Analysis/GRSimpleVals.h +++ b/clang/Analysis/GRSimpleVals.h @@ -52,10 +52,12 @@ public: // Calls. - virtual ValueState* EvalCall(ValueStateManager& StateMgr, - ValueManager& ValMgr, - CallExpr* CE, LVal L, - ValueState* St); + virtual void EvalCall(ExplodedNodeSet& Dst, + ValueStateManager& StateMgr, + GRStmtNodeBuilder& Builder, + ValueManager& ValMgr, + CallExpr* CE, LVal L, + ExplodedNode* Pred); protected: diff --git a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h index 423f4f065c1c..ca76c48387c2 100644 --- a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h +++ b/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h @@ -365,9 +365,10 @@ public: }; -template +template class ExplodedNodeSet { + typedef ExplodedNode NodeTy; typedef llvm::SmallPtrSet ImplTy; ImplTy Impl; diff --git a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h index 53986a326ff4..151f202dee4f 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -176,7 +176,7 @@ public: return static_cast(NB.generateNodeImpl(S, St)); } - NodeTy* Nodify(ExplodedNodeSet& Dst, Stmt* S, + NodeTy* Nodify(ExplodedNodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy* St) { // If the state hasn't changed, don't generate a new node. diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index ffbd064c30b5..c753249779e1 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -31,7 +31,7 @@ public: typedef GRBranchNodeBuilder BranchNodeBuilder; typedef GRIndirectGotoNodeBuilder IndirectGotoNodeBuilder; typedef GRSwitchNodeBuilder SwitchNodeBuilder; - typedef ExplodedNodeSet NodeSet; + typedef ExplodedNodeSet NodeSet; protected: /// G - the simulation graph. @@ -414,8 +414,9 @@ protected: return TF->EvalBinOp(ValMgr, Op, cast(L), cast(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); diff --git a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index a91a97b91a9c..ea8a79347167 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/clang/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -54,9 +54,11 @@ public: // Calls. - virtual ValueState* EvalCall(ValueStateManager& StateMgr, - ValueManager& ValMgr, CallExpr* CE, LVal L, - ValueState* St) = 0; + virtual void EvalCall(ExplodedNodeSet& Dst, + ValueStateManager& StateMgr, + GRStmtNodeBuilder& Builder, + ValueManager& ValMgr, CallExpr* CE, LVal L, + ExplodedNode* Pred) = 0; }; } // end clang namespace