]> granicus.if.org Git - clang/commitdiff
[leaks] Fix a leak of a basic block when we successfully fold a switch
authorChandler Carruth <chandlerc@gmail.com>
Sat, 3 May 2014 00:14:49 +0000 (00:14 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 3 May 2014 00:14:49 +0000 (00:14 +0000)
condition to a constant and emit only the relevant statement. In that
case, we were previously creating the epilog jump destination, a cleanup
scope, and emitting any condition variable into it. Instead, we can emit
the condition variable (if we have one) into the cleanup scope used for
the entire folded case sequence. We avoid creating a jump dest, a basic
block, and an extra cleanup scope. Win!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207888 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGStmt.cpp

index 9ea53b3e1fb81e0eb9dd81bf9d14043baae5ebc8..4e6f88df3e2aa59a4d0f9a509233bb5075ad6300 100644 (file)
@@ -1302,13 +1302,6 @@ static bool FindCaseStatementsForValue(const SwitchStmt &S,
 }
 
 void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
-  JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
-
-  RunCleanupsScope ConditionScope(*this);
-
-  if (S.getConditionVariable())
-    EmitAutoVarDecl(*S.getConditionVariable());
-
   // Handle nested switch statements.
   llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
   SmallVector<uint64_t, 16> *SavedSwitchWeights = SwitchWeights;
@@ -1328,6 +1321,11 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
       }
       RunCleanupsScope ExecutedScope(*this);
 
+      // Emit the condition variable if needed inside the entire cleanup scope
+      // used by this special case for constant folded switches.
+      if (S.getConditionVariable())
+        EmitAutoVarDecl(*S.getConditionVariable());
+
       // 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.
@@ -1348,6 +1346,11 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
     }
   }
 
+  JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
+
+  RunCleanupsScope ConditionScope(*this);
+  if (S.getConditionVariable())
+    EmitAutoVarDecl(*S.getConditionVariable());
   llvm::Value *CondV = EmitScalarExpr(S.getCond());
 
   // Create basic block to hold stuff that comes after switch