aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFG.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-07-22 22:56:04 +0000
committerMike Stump <mrs@apple.com>2009-07-22 22:56:04 +0000
commit0979d80615df97c675423de631c1b884819f4712 (patch)
tree18d1d588ec10fed6e56d062ecf078b61f3946c9f /lib/Analysis/CFG.cpp
parentf0549e2b5c73d65ce96fc37c9030577997fe19d4 (diff)
Improve CFG support for C++ throw expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76814 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFG.cpp')
-rw-r--r--lib/Analysis/CFG.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 4c2ecb92f6..f43631c4d0 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -99,6 +99,7 @@ private:
CFGBlock *VisitCompoundStmt(CompoundStmt *C);
CFGBlock *VisitConditionalOperator(ConditionalOperator *C);
CFGBlock *VisitContinueStmt(ContinueStmt *C);
+ CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T);
CFGBlock *VisitDeclStmt(DeclStmt *DS);
CFGBlock *VisitDeclSubExpr(Decl* D);
CFGBlock *VisitDefaultStmt(DefaultStmt *D);
@@ -319,6 +320,9 @@ tryAgain:
case Stmt::ObjCAtCatchStmtClass:
return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S));
+ case Stmt::CXXThrowExprClass:
+ return VisitCXXThrowExpr(cast<CXXThrowExpr>(S));
+
case Stmt::ObjCAtSynchronizedStmtClass:
return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S));
@@ -1262,6 +1266,23 @@ CFGBlock* CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) {
return VisitStmt(S, true);
}
+CFGBlock* CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr* T) {
+ // If we were in the middle of a block we stop processing that block and
+ // reverse its statements.
+ if (Block && !FinishBlock(Block))
+ return 0;
+
+ // Create the new block.
+ Block = createBlock(false);
+
+ // The Exit block is the only successor.
+ Block->addSuccessor(&cfg->getExit());
+
+ // Add the statement to the block. This may create new blocks if S contains
+ // control-flow (short-circuit operations).
+ return VisitStmt(T, true);
+}
+
CFGBlock *CFGBuilder::VisitDoStmt(DoStmt* D) {
// See if this is a known constant.
bool KnownTrue = false;