[cfe-commits] r148359 - in /cfe/trunk: lib/CodeGen/CGStmt.cpp test/CodeGenCXX/switch-case-folding-2.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Jan 17 15:39:50 PST 2012


Author: fjahanian
Date: Tue Jan 17 17:39:50 2012
New Revision: 148359

URL: http://llvm.org/viewvc/llvm-project?rev=148359&view=rev
Log:
Folding away unreachable case statement.
patch (slightly revised) by Aaron Ballman.


Added:
    cfe/trunk/test/CodeGenCXX/switch-case-folding-2.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGStmt.cpp

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=148359&r1=148358&r2=148359&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Jan 17 17:39:50 2012
@@ -883,10 +883,8 @@
   // 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 @@
   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 @@
                                    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

Added: cfe/trunk/test/CodeGenCXX/switch-case-folding-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/switch-case-folding-2.cpp?rev=148359&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/switch-case-folding-2.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/switch-case-folding-2.cpp Tue Jan 17 17:39:50 2012
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// CHECK that we don't crash.
+
+extern int printf(const char*, ...);
+int test(int val){
+ switch (val) {
+ case 4:
+   do {
+     switch (6) {
+       case 6: do { case 5: printf("bad\n"); } while (0);
+     };
+   } while (0);
+ }
+ return 0;
+}
+
+int main(void) {
+ return test(5);
+}
+
+// CHECK-NOT: call i32 (i8*, ...)* @printf(





More information about the cfe-commits mailing list