diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-16 23:05:51 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-16 23:05:51 +0000 |
commit | 6b31e8ed11721505645860f40486e091ecd23dd0 (patch) | |
tree | d9f4ee6f950830041c75672cef69b02e54d84e37 | |
parent | 5ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64 (diff) |
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
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 7 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRTransferFuncs.h | 12 | ||||
-rw-r--r-- | 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<ValueState>& Builder, CallExpr* CE, LVal L, - ExplodedNode<ValueState>* Pred) = 0; + ExplodedNode<ValueState>* Pred) {} virtual void EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst, GRExprEngine& Engine, GRStmtNodeBuilder<ValueState>& Builder, ObjCMessageExpr* ME, - ExplodedNode<ValueState>* Pred) = 0; + ExplodedNode<ValueState>* Pred) {} // Stores. @@ -88,6 +88,14 @@ public: virtual void EvalEndPath(GRExprEngine& Engine, GREndPathNodeBuilder<ValueState>& Builder) {} + + // Return statements. + + virtual void EvalReturn(ExplodedNodeSet<ValueState>& Dst, + GRExprEngine& Engine, + GRStmtNodeBuilder<ValueState>& Builder, + ReturnStmt* S, + ExplodedNode<ValueState>* 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<bool> 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; } } |