Fix iterator corruption in splitBasicBlockBefore
authorMax Kazantsev <mkazantsev@azul.com>
Thu, 27 Oct 2022 10:54:15 +0000 (17:54 +0700)
committerMax Kazantsev <mkazantsev@azul.com>
Thu, 27 Oct 2022 10:54:15 +0000 (17:54 +0700)
We should not delete block predecessors (via replacing successors
of terminators) while iterating them, otherwise we may skip some
of them. Instead, save predecessors to a separate vector and iterate
over it.

llvm/lib/IR/BasicBlock.cpp

index 687865d..20101a9 100644 (file)
@@ -452,7 +452,11 @@ BasicBlock *BasicBlock::splitBasicBlockBefore(iterator I, const Twine &BBName) {
   // If there were PHI nodes in 'this' block, the PHI nodes are updated
   // to reflect that the incoming branches will be from the New block and not
   // from predecessors of the 'this' block.
-  for (BasicBlock *Pred : predecessors(this)) {
+  // Save predecessors to separate vector before modifying them.
+  SmallVector<BasicBlock *, 4> Predecessors;
+  for (BasicBlock *Pred : predecessors(this))
+    Predecessors.push_back(Pred);
+  for (BasicBlock *Pred : Predecessors) {
     Instruction *TI = Pred->getTerminator();
     TI->replaceSuccessorWith(this, New);
     this->replacePhiUsesWith(Pred, New);