From 41a6780bace5d84b390adb0484ed755be8e73bda Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Wed, 29 Mar 2017 18:44:32 -0400 Subject: [PATCH] Deprecate BasicBlock.delete() with a stern warning Removing blocks from the CFG is not as easy as it might appear at first. Incorrect deletion of a block can cause dangling references to appear in the function which show up as bad accesses when deallocation of the parent function occurs. The safest way to remove a Basic Block is to first make sure that it is freshly inserted. Next, walk its instructions and, in turn, their uses and overwrite those uses with undef. Next, remove those instructions from the basic block one by one. Finally, call removeFromParent(). Do not attempt to delete() the block, the containing function will handle that when it goes to destroy the module. --- Sources/LLVM/BasicBlock.swift | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Sources/LLVM/BasicBlock.swift b/Sources/LLVM/BasicBlock.swift index 63ee2121..491a53b9 100644 --- a/Sources/LLVM/BasicBlock.swift +++ b/Sources/LLVM/BasicBlock.swift @@ -63,15 +63,11 @@ public struct BasicBlock: IRValue { } } - /// Deletes the basic block from its containing function. - /// - note: This does not remove breaks to this block from the - /// function. Ensure you have removed all instructions that reference - /// this basic block before deleting it. - public func delete() { - LLVMDeleteBasicBlock(llvm) - } - /// Removes this basic block from a function but keeps it alive. + /// + /// - note: To ensure correct removal of the block, you must invalidate any + /// references to it and its child instructions. The block must also + /// have no successor blocks that make reference to it. public func removeFromParent() { LLVMRemoveBasicBlockFromParent(llvm) } @@ -87,6 +83,18 @@ public struct BasicBlock: IRValue { } } +extension BasicBlock { + /// Deletes the basic block from its containing function. + /// - note: This does not remove breaks to this block from the + /// function. Ensure you have removed all instructions that reference + /// this basic block before deleting it. + @available(*, deprecated, message: "it is hard to use correctly and will be removed. See BasicBlock.removeFromParent() instead") + public func delete() { + LLVMDeleteBasicBlock(llvm) + } + +} + extension BasicBlock { /// An `Address` represents a function-relative address of a basic block for /// use with the `indirectbr` instruction.