+ // Remove implausible terminators and replace them with UnreachableInst.
+ for (auto &Funclet : FuncletBlocks) {
+ BasicBlock *FuncletPadBB = Funclet.first;
+ std::set<BasicBlock *> &BlocksInFunclet = Funclet.second;
+ Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
+ auto *CatchPad = dyn_cast<CatchPadInst>(FirstNonPHI);
+ auto *CleanupPad = dyn_cast<CleanupPadInst>(FirstNonPHI);
+
+ for (BasicBlock *BB : BlocksInFunclet) {
+ TerminatorInst *TI = BB->getTerminator();
+ // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
+ bool IsUnreachableRet = isa<ReturnInst>(TI) && (CatchPad || CleanupPad);
+ // The token consumed by a CatchReturnInst must match the funclet token.
+ bool IsUnreachableCatchret = false;
+ if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
+ IsUnreachableCatchret = CRI->getReturnValue() != CatchPad;
+ // The token consumed by a CleanupPadInst must match the funclet token.
+ bool IsUnreachableCleanupret = false;
+ if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
+ IsUnreachableCleanupret = CRI->getReturnValue() != CleanupPad;
+ if (IsUnreachableRet || IsUnreachableCatchret || IsUnreachableCleanupret) {
+ new UnreachableInst(BB->getContext(), TI);
+ TI->eraseFromParent();
+ }
+ }
+ }
+