From: Ted Kremenek Date: Wed, 4 Aug 2010 23:54:30 +0000 (+0000) Subject: Fix CFGBuilder to not blow out the stack when processing deeply nested CaseStmts... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0fc67e2d619088945ac71e9d2590d5158650885d;p=clang Fix CFGBuilder to not blow out the stack when processing deeply nested CaseStmts. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110286 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 821a578dbc..f8f26f6107 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -1617,9 +1617,30 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) { CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) { // CaseStmts are essentially labels, so they are the first statement in a // block. + CFGBlock *TopBlock = 0, *LastBlock = 0; + + if (Stmt *Sub = CS->getSubStmt()) { + // For deeply nested chains of CaseStmts, instead of doing a recursion + // (which can blow out the stack), manually unroll and create blocks + // along the way. + while (isa(Sub)) { + CFGBlock *CurrentBlock = createBlock(false); + CurrentBlock->setLabel(CS); + + if (TopBlock) + AddSuccessor(LastBlock, CurrentBlock); + else + TopBlock = CurrentBlock; + + AddSuccessor(SwitchTerminatedBlock, CurrentBlock); + LastBlock = CurrentBlock; - if (CS->getSubStmt()) - addStmt(CS->getSubStmt()); + CS = cast(Sub); + Sub = CS->getSubStmt(); + } + + addStmt(Sub); + } CFGBlock* CaseBlock = Block; if (!CaseBlock) @@ -1640,10 +1661,16 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) { // We set Block to NULL to allow lazy creation of a new block (if necessary) Block = NULL; - // This block is now the implicit successor of other blocks. - Succ = CaseBlock; + if (TopBlock) { + AddSuccessor(LastBlock, CaseBlock); + Succ = TopBlock; + } + else { + // This block is now the implicit successor of other blocks. + Succ = CaseBlock; + } - return CaseBlock; + return Succ; } CFGBlock* CFGBuilder::VisitDefaultStmt(DefaultStmt* Terminator) {