From a4309c941c622f45f5fe58faaa0227a7f8b4da16 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Sat, 18 Aug 2012 00:30:23 +0000 Subject: [analyzer] Treat C++ 'throw' as a sink. Our current handling of 'throw' is all CFG-based: it jumps to a 'catch' block if there is one and the function exit block if not. But this doesn't really get the right behavior when a function is inlined: execution will continue on the caller's side, which is always the wrong thing to do. Even within a single function, 'throw' completely skips any destructors that are to be run. This is essentially the same problem as @finally -- a CFGBlock that can have multiple entry points, whose exit points depend on whether it was entered normally or exceptionally. Representing 'throw' as a sink matches our current (non-)handling of @throw. It's not a perfect solution, but it's better than continuing analysis in an inconsistent or even impossible state. llvm-svn: 162157 --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'clang/lib') diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index e7b009a176e..c64a35eafbb 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -607,11 +607,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::AtomicExprClass: // Fall through. - // Currently all handling of 'throw' just falls to the CFG. We - // can consider doing more if necessary. - case Stmt::CXXThrowExprClass: - // Fall through. - // Cases we intentionally don't evaluate, since they don't need // to be explicitly evaluated. case Stmt::AddrLabelExprClass: @@ -886,12 +881,12 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, Bldr.addNodes(Dst); break; - case Stmt::ObjCAtThrowStmtClass: { + case Stmt::ObjCAtThrowStmtClass: + case Stmt::CXXThrowExprClass: // FIXME: This is not complete. We basically treat @throw as // an abort. Bldr.generateNode(S, Pred, Pred->getState(), /*IsSink=*/true); break; - } case Stmt::ReturnStmtClass: Bldr.takeNodes(Pred); -- cgit v1.2.3