[cfe-commits] r115668 - in /cfe/trunk: lib/CodeGen/CodeGenFunction.cpp test/CodeGenCXX/goto.cpp

John McCall rjmccall at apple.com
Tue Oct 5 13:48:16 PDT 2010


Author: rjmccall
Date: Tue Oct  5 15:48:15 2010
New Revision: 115668

URL: http://llvm.org/viewvc/llvm-project?rev=115668&view=rev
Log:
Teach PopCleanupBlock to correctly handle the possibility of branching through
a EH-only cleanup as part of a fallthrough branch-through.  That this happens
for this test case is actually a separate bug.


Added:
    cfe/trunk/test/CodeGenCXX/goto.cpp
Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=115668&r1=115667&r2=115668&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Oct  5 15:48:15 2010
@@ -846,26 +846,31 @@
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
   bool HasFallthrough = (FallthroughSource != 0 && IsActive);
 
-  // As a kindof crazy internal case, branch-through fall-throughs
-  // leave the insertion point set to the end of the last cleanup.
+  // Branch-through fall-throughs leave the insertion point set to the
+  // end of the last cleanup, which points to the current scope.  The
+  // rest of IR gen doesn't need to worry about this; it only happens
+  // during the execution of PopCleanupBlocks().
   bool HasPrebranchedFallthrough =
     (FallthroughSource && FallthroughSource->getTerminator());
 
+  // If this is a normal cleanup, then having a prebranched
+  // fallthrough implies that the fallthrough source unconditionally
+  // jumps here.
+  assert(!Scope.isNormalCleanup() || !HasPrebranchedFallthrough ||
+         (Scope.getNormalBlock() &&
+          FallthroughSource->getTerminator()->getSuccessor(0)
+            == Scope.getNormalBlock()));
+
   bool RequiresNormalCleanup = false;
   if (Scope.isNormalCleanup() &&
       (HasFixups || HasExistingBranches || HasFallthrough)) {
     RequiresNormalCleanup = true;
   }
 
-  assert(!HasPrebranchedFallthrough || RequiresNormalCleanup || !IsActive);
-  assert(!HasPrebranchedFallthrough ||
-         (Scope.isNormalCleanup() && Scope.getNormalBlock() &&
-          FallthroughSource->getTerminator()->getSuccessor(0)
-            == Scope.getNormalBlock()));
-
   // Even if we don't need the normal cleanup, we might still have
   // prebranched fallthrough to worry about.
-  if (!RequiresNormalCleanup && HasPrebranchedFallthrough) {
+  if (Scope.isNormalCleanup() && !RequiresNormalCleanup &&
+      HasPrebranchedFallthrough) {
     assert(!IsActive);
 
     llvm::BasicBlock *NormalEntry = Scope.getNormalBlock();

Added: cfe/trunk/test/CodeGenCXX/goto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/goto.cpp?rev=115668&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/goto.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/goto.cpp Tue Oct  5 15:48:15 2010
@@ -0,0 +1,29 @@
+// RUN: %clang-cc1 %s -fexceptions
+
+// Reduced from a crash on boost::interprocess's node_allocator_test.cpp.
+namespace test0 {
+  struct A { A(); ~A(); };
+  struct V { V(const A &a = A()); ~V(); };
+
+  template<int X> int vector_test()
+  {
+   A process_name;
+   try {
+     A segment;
+
+     V *stdvector = new V();
+
+     int x = 5, y = 7;
+     if(x == y) return 1;
+   }
+   catch(int ex){
+     return 1;
+   }
+   return 0;
+}
+
+int main ()
+{
+  return vector_test<0>();
+}
+}





More information about the cfe-commits mailing list