diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-31 15:02:58 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-31 15:02:58 +0000 |
commit | 02737ed29d7fff2206f7c7ee958cdf0665e35542 (patch) | |
tree | e50ad83a50d1573a5d090506dd60caff4c56ae7f /lib/Analysis/GRExprEngine.cpp | |
parent | 8a934233d1582b5bde9d270bc0705aa81e471a79 (diff) |
Added path-sensitive check for return statements that return the address
of a stack variable. This is the path-sensitive version of a check that
is already done during semantic analysis.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48980 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index b70e21977b..bf0d5ea395 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1190,6 +1190,50 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME, MakeNode(Dst, ME, Pred, St); } +void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) { + + Expr* R = S->getRetValue(); + + if (!R) { + Dst.Add(Pred); + return; + } + + QualType T = R->getType(); + + if (T->isPointerType() || T->isReferenceType()) { + + // Check if any of the return values return the address of a stack variable. + + NodeSet Tmp; + Visit(R, Pred, Tmp); + + for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { + RVal X = GetRVal((*I)->getState(), R); + + if (isa<lval::DeclVal>(X)) { + + if (cast<lval::DeclVal>(X).getDecl()->hasLocalStorage()) { + + // Create a special node representing the v + + NodeTy* RetStackNode = Builder->generateNode(S, GetState(*I), *I); + + if (RetStackNode) { + RetStackNode->markAsSink(); + RetsStackAddr.insert(RetStackNode); + } + + continue; + } + } + + Dst.Add(*I); + } + } + else + Visit(R, Pred, Dst); +} void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, GRExprEngine::NodeTy* Pred, @@ -1625,14 +1669,8 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { // that users can quickly query what was the state at the // exit points of a function. - case Stmt::ReturnStmtClass: { - if (Expr* R = cast<ReturnStmt>(S)->getRetValue()) - Visit(R, Pred, Dst); - else - Dst.Add(Pred); - - break; - } + case Stmt::ReturnStmtClass: + VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst); break; case Stmt::UnaryOperatorClass: { UnaryOperator* U = cast<UnaryOperator>(S); |