diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-12-23 03:59:04 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-12-23 03:59:04 +0000 |
| commit | c640f863e03ec8df606858e054025bec8fc2507c (patch) | |
| tree | 3ad9fa641feff3638c6706e0a97c7e083a57521c /llvm/lib | |
| parent | ce7d39d5e1724e1643f784c1bc625522dcdbfc42 (diff) | |
| download | bcm5719-llvm-c640f863e03ec8df606858e054025bec8fc2507c.tar.gz bcm5719-llvm-c640f863e03ec8df606858e054025bec8fc2507c.zip | |
[WinEH] Don't visit the same catchswitch twice
We visited the same catchswitch twice because it was both the child of
another funclet and the predecessor of a cleanuppad.
Instead, change the numbering algorithm to only recurse if the unwind
destination of the inner funclet agrees with the unwind destination of
the catchswitch.
This fixes PR25926.
llvm-svn: 256317
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/WinEHPrepare.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index 3b076b65e69..dc9f78f006a 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -165,8 +165,7 @@ static void calculateStateNumbersForInvokes(const Function *Fn, continue; auto &BBColors = BlockColors[&BB]; - assert(BBColors.size() == 1 && - "multi-color BB not removed by preparation"); + assert(BBColors.size() == 1 && "multi-color BB not removed by preparation"); BasicBlock *FuncletEntryBB = BBColors.front(); BasicBlock *FuncletUnwindDest; @@ -249,8 +248,13 @@ static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow; for (const User *U : CatchPad->users()) { const auto *UserI = cast<Instruction>(U); - if (UserI->isEHPad()) - calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); + if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) + if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest()) + calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); + if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) + if (getCleanupRetUnwindDest(InnerCleanupPad) == + CatchSwitch->getUnwindDest()) + calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); } } int CatchHigh = FuncInfo.getLastStateNumber(); @@ -347,9 +351,13 @@ static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo, // outside the __try. for (const User *U : CatchPad->users()) { const auto *UserI = cast<Instruction>(U); - if (UserI->isEHPad()) { - calculateSEHStateNumbers(FuncInfo, UserI, ParentState); - } + if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) + if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest()) + calculateSEHStateNumbers(FuncInfo, UserI, ParentState); + if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) + if (getCleanupRetUnwindDest(InnerCleanupPad) == + CatchSwitch->getUnwindDest()) + calculateSEHStateNumbers(FuncInfo, UserI, ParentState); } } else { auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI); |

