diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2012-01-17 23:39:50 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-01-17 23:39:50 +0000 |
| commit | 9ce39e299d5d141e449681c47397dc99d3b8ebaa (patch) | |
| tree | 68da8249a622b5a036c5427db88ba93792b1b150 /clang/lib/CodeGen | |
| parent | a95f9aaa843250e64221fbd34e04ee235e3985dc (diff) | |
| download | bcm5719-llvm-9ce39e299d5d141e449681c47397dc99d3b8ebaa.tar.gz bcm5719-llvm-9ce39e299d5d141e449681c47397dc99d3b8ebaa.zip | |
Folding away unreachable case statement.
patch (slightly revised) by Aaron Ballman.
llvm-svn: 148359
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index ee4a272ea88..c7a8cf6a7d5 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -883,10 +883,8 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { // when we've constant-folded the switch, are emitting the constant case, // and part of the constant case includes another case statement. For // instance: switch (4) { case 4: do { case 5: } while (1); } - if (!SwitchInsn) { - EmitStmt(S.getSubStmt()); + if (!SwitchInsn) return; - } // Handle case ranges. if (S.getRHS()) { @@ -1162,6 +1160,10 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { if (S.getConditionVariable()) EmitAutoVarDecl(*S.getConditionVariable()); + // Handle nested switch statements. + llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; + llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; + // See if we can constant fold the condition of the switch and therefore only // emit the live case statement (if any) of the switch. llvm::APInt ConstantCondValue; @@ -1171,20 +1173,26 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { getContext())) { RunCleanupsScope ExecutedScope(*this); + // At this point, we are no longer "within" a switch instance, so + // we can temporarily enforce this to ensure that any embedded case + // statements are not emitted. + SwitchInsn = 0; + // Okay, we can dead code eliminate everything except this case. Emit the // specified series of statements and we're good. for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) EmitStmt(CaseStmts[i]); + + // Now we want to restore the saved switch instance so that nested switches + // continue to function properly + SwitchInsn = SavedSwitchInsn; + return; } } llvm::Value *CondV = EmitScalarExpr(S.getCond()); - // Handle nested switch statements. - llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; - llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; - // Create basic block to hold stuff that comes after switch // statement. We also need to create a default block now so that // explicit case ranges tests can have a place to jump to on |

