summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFedor Indutny <fedor@indutny.com>2018-03-03 22:34:38 +0000
committerFedor Indutny <fedor@indutny.com>2018-03-03 22:34:38 +0000
commit364b9c2adb633280509db32c7afe869e010c695f (patch)
treef1ecbe60d75682d068bd7e0cac632125f5d6b3bc
parentf90054dd90b86410bc8464f21e0f75b82ecedb6d (diff)
downloadbcm5719-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.cpp9
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();
OpenPOWER on IntegriCloud