Skip to content

Commit 41a6780

Browse files
committed
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.
1 parent 7bc5935 commit 41a6780

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

Sources/LLVM/BasicBlock.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,11 @@ public struct BasicBlock: IRValue {
6363
}
6464
}
6565

66-
/// Deletes the basic block from its containing function.
67-
/// - note: This does not remove breaks to this block from the
68-
/// function. Ensure you have removed all instructions that reference
69-
/// this basic block before deleting it.
70-
public func delete() {
71-
LLVMDeleteBasicBlock(llvm)
72-
}
73-
7466
/// Removes this basic block from a function but keeps it alive.
67+
///
68+
/// - note: To ensure correct removal of the block, you must invalidate any
69+
/// references to it and its child instructions. The block must also
70+
/// have no successor blocks that make reference to it.
7571
public func removeFromParent() {
7672
LLVMRemoveBasicBlockFromParent(llvm)
7773
}
@@ -87,6 +83,18 @@ public struct BasicBlock: IRValue {
8783
}
8884
}
8985

86+
extension BasicBlock {
87+
/// Deletes the basic block from its containing function.
88+
/// - note: This does not remove breaks to this block from the
89+
/// function. Ensure you have removed all instructions that reference
90+
/// this basic block before deleting it.
91+
@available(*, deprecated, message: "it is hard to use correctly and will be removed. See BasicBlock.removeFromParent() instead")
92+
public func delete() {
93+
LLVMDeleteBasicBlock(llvm)
94+
}
95+
96+
}
97+
9098
extension BasicBlock {
9199
/// An `Address` represents a function-relative address of a basic block for
92100
/// use with the `indirectbr` instruction.

0 commit comments

Comments
 (0)