diff options
author | Fedor Indutny <fedor@indutny.com> | 2018-03-03 22:34:38 +0000 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2018-03-03 22:34:38 +0000 |
commit | 364b9c2adb633280509db32c7afe869e010c695f (patch) | |
tree | f1ecbe60d75682d068bd7e0cac632125f5d6b3bc | |
parent | f90054dd90b86410bc8464f21e0f75b82ecedb6d (diff) | |
download | bcm5719-llvm-364b9c2adb633280509db32c7afe869e010c695f.tar.gz bcm5719-llvm-364b9c2adb633280509db32c7afe869e010c695f.zip |
[CallSiteSplitting] fix use after-free
Iterating through predecessors of `TailBB` while removing their
terminators leads to use after-free, because the predecessor list is
changing on each removal.
llvm-svn: 326668
-rw-r--r-- | llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp index 3ab012a084e..dcd21e843c6 100644 --- a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp +++ b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp @@ -347,8 +347,13 @@ static void splitCallSite( // FIXME: remove TI in `copyMustTailReturn` if (IsMustTailCall) { // Remove superfluous `br` terminators from the end of the Split blocks - for (BasicBlock *SplitBlock : predecessors(TailBB)) - SplitBlock->getTerminator()->eraseFromParent(); + // NOTE: Removing terminator removes the SplitBlock from the TailBB's + // predecessors. Therefore we must get complete list of Splits before + // attempting removal. + SmallVector<BasicBlock *, 2> Splits(predecessors((TailBB))); + assert(Splits.size() == 2 && "Expected exactly 2 splits!"); + for (unsigned i = 0; i < Splits.size(); i++) + Splits[i]->getTerminator()->eraseFromParent(); // Erase the tail block once done with musttail patching TailBB->eraseFromParent(); |