diff options
-rw-r--r-- | AST/CFG.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/AST/CFG.cpp b/AST/CFG.cpp index 51b8cb5240..eb39fdfc01 100644 --- a/AST/CFG.cpp +++ b/AST/CFG.cpp @@ -65,6 +65,7 @@ class VISIBILITY_HIDDEN CFGBuilder : public StmtVisitor<CFGBuilder,CFGBlock*> { CFGBlock* ContinueTargetBlock; CFGBlock* BreakTargetBlock; CFGBlock* SwitchTerminatedBlock; + bool SwitchHasDefaultCase; // LabelMap records the mapping from Label expressions to their blocks. typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy; @@ -109,6 +110,7 @@ public: CFGBlock* VisitBreakStmt(BreakStmt* B); CFGBlock* VisitSwitchStmt(SwitchStmt* S); CFGBlock* VisitSwitchCase(SwitchCase* S); + CFGBlock* VisitDefaultStmt(DefaultStmt* D); CFGBlock* VisitIndirectGotoStmt(IndirectGotoStmt* I); private: @@ -884,6 +886,9 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* S) { SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock), save_break(BreakTargetBlock); + SaveAndRestore<bool> save_has_default_case(SwitchHasDefaultCase); + SwitchHasDefaultCase = false; + // Create a new block that will contain the switch statement. SwitchTerminatedBlock = createBlock(false); @@ -900,10 +905,16 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* S) { CFGBlock *BodyBlock = Visit(S->getBody()); if (Block) FinishBlock(BodyBlock); + // If we have no "default:" case, the default transition is to the + // code following the switch body. + if (!SwitchHasDefaultCase) + SwitchTerminatedBlock->addSuccessor(SwitchSuccessor); + // Add the terminator and condition in the switch block. SwitchTerminatedBlock->setTerminator(S); assert (S->getCond() && "switch condition must be non-NULL"); Block = SwitchTerminatedBlock; + return addStmt(S->getCond()); } @@ -933,6 +944,11 @@ CFGBlock* CFGBuilder::VisitSwitchCase(SwitchCase* S) { return CaseBlock; } + +CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* D) { + SwitchHasDefaultCase = true; + return VisitSwitchCase(D); +} CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) { // Lazily create the indirect-goto dispatch block if there isn't one |