aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-01-17 23:39:50 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-01-17 23:39:50 +0000
commit985df1c1f2d0666a09bc03f3593929286b0dea65 (patch)
treef304739a55cf8f8a09bf91e11807462d5260bfda /lib/CodeGen/CGStmt.cpp
parent65a1e6707de0d6641e70d0a6edd7593fae85df3c (diff)
Folding away unreachable case statement.
patch (slightly revised) by Aaron Ballman. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGStmt.cpp')
-rw-r--r--lib/CodeGen/CGStmt.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index ee4a272ea8..c7a8cf6a7d 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/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