]> granicus.if.org Git - clang/commitdiff
When destroying a cleanup, kill any references to instructions in the entry
authorJohn McCall <rjmccall@apple.com>
Tue, 6 Jul 2010 17:35:03 +0000 (17:35 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 6 Jul 2010 17:35:03 +0000 (17:35 +0000)
block before deleting it.  Fixes PR7575.

This really just a short-term fix before implementing lazy cleanups.

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

lib/CodeGen/CodeGenFunction.cpp
test/CodeGenCXX/destructors.cpp

index 306989f11e2a20958e392434f0a684d7dca7a128..9375b77360cc7c1e8b6b1c3f0dc161e16ce60f5a 100644 (file)
@@ -688,6 +688,12 @@ static void DestroyCleanup(CodeGenFunction &CGF,
     llvm::BranchInst::Create(CGF.getUnreachableBlock(), Exit);
 
   assert(!Entry->getParent() && "cleanup entry already positioned?");
+  // We can't just delete the entry; we have to kill any references to
+  // its instructions in other blocks.
+  for (llvm::BasicBlock::iterator I = Entry->begin(), E = Entry->end();
+         I != E; ++I)
+    if (!I->use_empty())
+      I->replaceAllUsesWith(llvm::UndefValue::get(I->getType()));
   delete Entry;
 }
 
index ee8f1a5f543fb4d3e08e047eaf1e77cf6b470d2b..965aea52ee39759fc6f86fae0a0f21a26b2c93e5 100644 (file)
@@ -228,6 +228,37 @@ namespace test4 {
   }
 }
 
+// PR7575
+namespace test5 {
+  struct A { ~A(); };
+
+  // This is really unnecessarily verbose; we should be using phis,
+  // even at -O0.
+
+  // CHECK: define void @_ZN5test53fooEv()
+  // CHECK:      [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
+  // CHECK-NEXT: [[IVAR:%.*]] = alloca i64
+  // CHECK:      [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]]
+  // CHECK-NEXT: store i64 5, i64* [[IVAR]]
+  // CHECK-NEXT: br label
+  // CHECK:      [[I:%.*]] = load i64* [[IVAR]]
+  // CHECK-NEXT: icmp ne i64 [[I]], 0
+  // CHECK-NEXT: br i1
+  // CHECK:      [[I:%.*]] = load i64* [[IVAR]]
+  // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1
+  // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]]
+  // CHECK-NEXT: call void @_ZN5test51AD1Ev(
+  // CHECK-NEXT: br label
+  // CHECK:      [[I:%.*]] = load i64* [[IVAR]]
+  // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1
+  // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]]
+  // CHECK-NEXT: br label
+  // CHECK:      ret void
+  void foo() {
+    A elems[5];
+  }
+}
+
 // Checks from test3:
 
   // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(