aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-18 00:30:23 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-18 00:30:23 +0000
commitc32a453e40b2c8878fed10512fb2f570b7aba576 (patch)
treec2478526f43d1daba84c62d04fa57e9a78db9a5e /lib/StaticAnalyzer/Core/ExprEngine.cpp
parent19275bdec34b2ec5d77a78c0ea393a45ab05e128 (diff)
[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. <rdar://problem/12113713> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162157 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp9
1 files changed, 2 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index e7b009a176..c64a35eafb 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/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);