From 6b31e8ed11721505645860f40486e091ecd23dd0 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 16 Apr 2008 23:05:51 +0000 Subject: [PATCH] Handle ReturnStmts by dispatching to "EvalReturn" in the transfer function object. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49826 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/GRExprEngine.h | 7 +--- .../Analysis/PathSensitive/GRTransferFuncs.h | 12 +++++- lib/Analysis/GRExprEngine.cpp | 37 ++++++++++++++----- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 342da36d51..0d26d98ad0 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -602,13 +602,10 @@ protected: TF->EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred); } - void VisitStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St, + void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St, RVal TargetLV, RVal Val); - void EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, ValueState* St, - RVal TargetLV, RVal Val) { - TF->EvalStore(Dst, *this, *Builder, E, Pred, St, TargetLV, Val); - } + void EvalReturn(NodeSet& Dst, ReturnStmt* s, NodeTy* Pred); ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken); }; diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index 6bfc918e3a..d49144f355 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -64,13 +64,13 @@ public: GRExprEngine& Engine, GRStmtNodeBuilder& Builder, CallExpr* CE, LVal L, - ExplodedNode* Pred) = 0; + ExplodedNode* Pred) {} virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst, GRExprEngine& Engine, GRStmtNodeBuilder& Builder, ObjCMessageExpr* ME, - ExplodedNode* Pred) = 0; + ExplodedNode* Pred) {} // Stores. @@ -88,6 +88,14 @@ public: virtual void EvalEndPath(GRExprEngine& Engine, GREndPathNodeBuilder& Builder) {} + + // Return statements. + + virtual void EvalReturn(ExplodedNodeSet& Dst, + GRExprEngine& Engine, + GRStmtNodeBuilder& Builder, + ReturnStmt* S, + ExplodedNode* Pred) {} }; } // end clang namespace diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 53567c184e..418129caa9 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -708,8 +708,8 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst){ MakeNode(Dst, D, Pred, SetBlkExprRVal(St, D, Y)); } -void GRExprEngine::VisitStore(NodeSet& Dst, Expr* E, NodeTy* Pred, - ValueState* St, RVal TargetLV, RVal Val) { +void GRExprEngine::EvalStore(NodeSet& Dst, Expr* E, NodeTy* Pred, + ValueState* St, RVal TargetLV, RVal Val) { assert (Builder && "GRStmtNodeBuilder must be defined."); @@ -718,7 +718,7 @@ void GRExprEngine::VisitStore(NodeSet& Dst, Expr* E, NodeTy* Pred, assert (!TargetLV.isUndef()); - EvalStore(Dst, E, Pred, St, TargetLV, Val); + TF->EvalStore(Dst, *this, *Builder, E, Pred, St, TargetLV, Val); // Handle the case where no nodes where generated. Auto-generate that // contains the updated state if we aren't generating sinks. @@ -1456,15 +1456,31 @@ void GRExprEngine::VisitAsmStmtHelperInputs(AsmStmt* A, VisitAsmStmtHelperInputs(A, I, E, *NI, Dst); } +void GRExprEngine::EvalReturn(NodeSet& Dst, ReturnStmt* S, NodeTy* Pred) { + assert (Builder && "GRStmtNodeBuilder must be defined."); + + unsigned size = Dst.size(); + SaveAndRestore OldSink(Builder->BuildSinks); + + TF->EvalReturn(Dst, *this, *Builder, S, Pred); + + // Handle the case where no nodes where generated. Auto-generate that + // contains the updated state if we aren't generating sinks. + + if (!Builder->BuildSinks && Dst.size() == size) + MakeNode(Dst, S, Pred, GetState(Pred)); +} + void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) { Expr* R = S->getRetValue(); if (!R) { - Dst.Add(Pred); + EvalReturn(Dst, S, Pred); return; } - + + NodeSet DstRet; QualType T = R->getType(); if (T->isPointerLikeType()) { @@ -1494,11 +1510,14 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) { } } - Dst.Add(*I); + DstRet.Add(*I); } } else - Visit(R, Pred, Dst); + Visit(R, Pred, DstRet); + + for (NodeSet::iterator I=DstRet.begin(), E=DstRet.end(); I!=E; ++I) + EvalReturn(Dst, S, *I); } //===----------------------------------------------------------------------===// @@ -1649,7 +1668,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, // Simulate the effects of a "store": bind the value of the RHS // to the L-Value represented by the LHS. - VisitStore(Dst, B, N2, SetRVal(St, B, RightV), + EvalStore(Dst, B, N2, SetRVal(St, B, RightV), LeftV, RightV); continue; @@ -1799,7 +1818,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, } // St = SetRVal(SetRVal(St, B, Result), LeftLV, Result); - VisitStore(Dst, B, N2, SetRVal(St, B, Result), LeftLV, Result); + EvalStore(Dst, B, N2, SetRVal(St, B, Result), LeftLV, Result); continue; } } -- 2.40.0