summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2010-01-20 01:15:34 +0000
committerMike Stump <mrs@apple.com>2010-01-20 01:15:34 +0000
commit0bdba6cdd8b1e2dc2c1fe8ae654356ff0e2da7e0 (patch)
tree72d7d74868ec3f11754a99447a0793cac36d889f /clang/lib
parent52606ff2ca538be70c249c225848e2f630e4c9ee (diff)
downloadbcm5719-llvm-0bdba6cdd8b1e2dc2c1fe8ae654356ff0e2da7e0.tar.gz
bcm5719-llvm-0bdba6cdd8b1e2dc2c1fe8ae654356ff0e2da7e0.zip
Add an exceptional edge from the try terminated block to the outer EH
context (try or the Exit block) when there isn't a catch (...). Improve CFG printing for catch (...). llvm-svn: 93962
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/CFG.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 6508c351f0e..33c3f551dd9 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -1599,6 +1599,7 @@ CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
} else TrySuccessor = Succ;
// Save the current "try" context.
+ CFGBlock *PrevTryTerminatedBlock = TryTerminatedBlock;
SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock);
// Create a new block that will contain the try statement.
@@ -1606,10 +1607,14 @@ CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
// Add the terminator in the try block.
TryTerminatedBlock->setTerminator(Terminator);
+ bool HasCatchAll = false;
for (unsigned h = 0; h <Terminator->getNumHandlers(); ++h) {
// The code after the try is the implicit successor.
Succ = TrySuccessor;
CXXCatchStmt *CS = Terminator->getHandler(h);
+ if (CS->getExceptionDecl() == 0) {
+ HasCatchAll = true;
+ }
Block = NULL;
CFGBlock *CatchBlock = VisitCXXCatchStmt(CS);
if (CatchBlock == 0)
@@ -1618,6 +1623,12 @@ CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
// statement.
AddSuccessor(TryTerminatedBlock, CatchBlock);
}
+ if (!HasCatchAll) {
+ if (PrevTryTerminatedBlock)
+ AddSuccessor(TryTerminatedBlock, PrevTryTerminatedBlock);
+ else
+ AddSuccessor(TryTerminatedBlock, &cfg->getExit());
+ }
// The code after the try is the implicit successor.
Succ = TrySuccessor;
@@ -2037,8 +2048,11 @@ static void print_block(llvm::raw_ostream& OS, const CFG* cfg,
OS << "default";
else if (CXXCatchStmt *CS = dyn_cast<CXXCatchStmt>(Label)) {
OS << "catch (";
- CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper->getLangOpts()),
- 0);
+ if (CS->getExceptionDecl())
+ CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper->getLangOpts()),
+ 0);
+ else
+ OS << "...";
OS << ")";
} else
OpenPOWER on IntegriCloud