[cfe-commits] r47087 - /cfe/trunk/AST/CFG.cpp

Ted Kremenek kremenek at apple.com
Wed Feb 13 13:46:35 PST 2008


Author: kremenek
Date: Wed Feb 13 15:46:34 2008
New Revision: 47087

URL: http://llvm.org/viewvc/llvm-project?rev=47087&view=rev
Log:
Fixed bug in CFG construction when processing switch statements that contain no
"default" case. In such cases, we now correctly add the CFGBlock representing
the code after the switch statement as a successor to the block terminated by
the switch statement.

Modified:
    cfe/trunk/AST/CFG.cpp

Modified: cfe/trunk/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/CFG.cpp?rev=47087&r1=47086&r2=47087&view=diff

==============================================================================
--- cfe/trunk/AST/CFG.cpp (original)
+++ cfe/trunk/AST/CFG.cpp Wed Feb 13 15:46:34 2008
@@ -65,6 +65,7 @@
   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 @@
   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 @@
   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 *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 @@
   
   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





More information about the cfe-commits mailing list