fix an issue where the verifier would reject a function whose entry
authorChris Lattner <sabre@nondot.org>
Sun, 1 Nov 2009 04:08:01 +0000 (04:08 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 1 Nov 2009 04:08:01 +0000 (04:08 +0000)
block had its address taken even if the blockaddress was dead.

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

include/llvm/BasicBlock.h
lib/VMCore/Globals.cpp
lib/VMCore/Verifier.cpp

index 10f2577869eca240214f69b0502ce8bf11e5f7e1..11afa4047787bedd986c9f5b651774eb26a391e9 100644 (file)
@@ -240,6 +240,10 @@ public:
   /// hasAddressTaken - returns true if there are any uses of this basic block
   /// other than direct branches, switches, etc. to it.
   bool hasAddressTaken() const { return SubclassData != 0; }
+                     
+  /// removeDeadBlockAddress - If there is a blockaddress node for this basic
+  /// block, try to remove it and any dead constant users of it.
+  void removeDeadBlockAddress();
 private:
   /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
   /// objects using it.  This is almost always 0, sometimes one, possibly but
index d18a20162dd9e223899f1a1d4789fe9b2863acd1..763fc721e09b63986778d4b1e40c00f0709df7eb 100644 (file)
@@ -75,6 +75,14 @@ void GlobalValue::removeDeadConstantUsers() const {
   }
 }
 
+/// removeDeadBlockAddress - If there is a blockaddress node for this basic
+/// block, try to remove it and any dead constant users of it.
+void BasicBlock::removeDeadBlockAddress() {
+  if (!hasAddressTaken()) return;
+  removeDeadUsersOfConstant(BlockAddress::get(this));
+}
+
+
 /// Override destroyConstant to make sure it doesn't get called on
 /// GlobalValue's because they shouldn't be treated like other constants.
 void GlobalValue::destroyConstant() {
index fc90148b8b5a98471f17e5f958952174ef807ad1..6b10d69ac5ed0b286223693cefe46f73639d20dd 100644 (file)
@@ -658,8 +658,13 @@ void Verifier::visitFunction(Function &F) {
     BasicBlock *Entry = &F.getEntryBlock();
     Assert1(pred_begin(Entry) == pred_end(Entry),
             "Entry block to function must not have predecessors!", Entry);
-    Assert1(!Entry->hasAddressTaken(),
-            "blockaddress may not be used with the entry block!", Entry);
+    
+    // The address of the entry block cannot be taken, unless it is dead.
+    if (Entry->hasAddressTaken()) {
+      Entry->removeDeadBlockAddress();
+      Assert1(!Entry->hasAddressTaken(),
+              "blockaddress may not be used with the entry block!", Entry);
+    }
   }
   
   // If this function is actually an intrinsic, verify that it is only used in