+void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
+ visitEHPadPredecessors(CPI);
+
+ BasicBlock *BB = CPI.getParent();
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CatchPadInst needs to be in a function with a personality.", &CPI);
+
+ // The catchpad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CPI,
+ "CatchPadInst not the first non-PHI instruction in the block.",
+ &CPI);
+
+ if (!BB->getSinglePredecessor())
+ for (BasicBlock *PredBB : predecessors(BB)) {
+ Assert(!isa<CatchPadInst>(PredBB->getTerminator()),
+ "CatchPadInst with CatchPadInst predecessor cannot have any other "
+ "predecessors.",
+ &CPI);
+ }
+
+ BasicBlock *UnwindDest = CPI.getUnwindDest();
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(
+ isa<CatchPadInst>(I) || isa<CatchEndPadInst>(I),
+ "CatchPadInst must unwind to a CatchPadInst or a CatchEndPadInst.",
+ &CPI);
+
+ visitTerminatorInst(CPI);
+}
+
+void Verifier::visitCatchEndPadInst(CatchEndPadInst &CEPI) {
+ visitEHPadPredecessors(CEPI);
+
+ BasicBlock *BB = CEPI.getParent();
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CatchEndPadInst needs to be in a function with a personality.",
+ &CEPI);
+
+ // The catchendpad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CEPI,
+ "CatchEndPadInst not the first non-PHI instruction in the block.",
+ &CEPI);
+
+ unsigned CatchPadsSeen = 0;
+ for (BasicBlock *PredBB : predecessors(BB))
+ if (isa<CatchPadInst>(PredBB->getTerminator()))
+ ++CatchPadsSeen;
+
+ Assert(CatchPadsSeen <= 1, "CatchEndPadInst must have no more than one "
+ "CatchPadInst predecessor.",
+ &CEPI);
+
+ if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) {
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(
+ I->isEHPad() && !isa<LandingPadInst>(I),
+ "CatchEndPad must unwind to an EH block which is not a landingpad.",
+ &CEPI);
+ }
+
+ visitTerminatorInst(CEPI);
+}
+
+void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) {
+ visitEHPadPredecessors(CPI);
+
+ BasicBlock *BB = CPI.getParent();
+
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CleanupPadInst needs to be in a function with a personality.", &CPI);
+
+ // The cleanuppad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CPI,
+ "CleanupPadInst not the first non-PHI instruction in the block.",
+ &CPI);
+
+ User *FirstUser = nullptr;
+ BasicBlock *FirstUnwindDest = nullptr;
+ for (User *U : CPI.users()) {
+ BasicBlock *UnwindDest;
+ if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(U)) {
+ UnwindDest = CRI->getUnwindDest();
+ } else {
+ UnwindDest = cast<CleanupEndPadInst>(U)->getUnwindDest();
+ }
+
+ if (!FirstUser) {
+ FirstUser = U;
+ FirstUnwindDest = UnwindDest;
+ } else {
+ Assert(UnwindDest == FirstUnwindDest,
+ "Cleanuprets/cleanupendpads from the same cleanuppad must "
+ "have the same unwind destination",
+ FirstUser, U);
+ }
+ }
+
+ visitInstruction(CPI);
+}
+
+void Verifier::visitCleanupEndPadInst(CleanupEndPadInst &CEPI) {
+ visitEHPadPredecessors(CEPI);
+
+ BasicBlock *BB = CEPI.getParent();
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "CleanupEndPadInst needs to be in a function with a personality.",
+ &CEPI);
+
+ // The cleanupendpad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &CEPI,
+ "CleanupEndPadInst not the first non-PHI instruction in the block.",
+ &CEPI);
+
+ if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) {
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(
+ I->isEHPad() && !isa<LandingPadInst>(I),
+ "CleanupEndPad must unwind to an EH block which is not a landingpad.",
+ &CEPI);
+ }
+
+ visitTerminatorInst(CEPI);
+}
+
+void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) {
+ if (BasicBlock *UnwindDest = CRI.getUnwindDest()) {
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(I->isEHPad() && !isa<LandingPadInst>(I),
+ "CleanupReturnInst must unwind to an EH block which is not a "
+ "landingpad.",
+ &CRI);
+ }
+
+ visitTerminatorInst(CRI);
+}
+
+void Verifier::visitTerminatePadInst(TerminatePadInst &TPI) {
+ visitEHPadPredecessors(TPI);
+
+ BasicBlock *BB = TPI.getParent();
+ Function *F = BB->getParent();
+ Assert(F->hasPersonalityFn(),
+ "TerminatePadInst needs to be in a function with a personality.",
+ &TPI);
+
+ // The terminatepad instruction must be the first non-PHI instruction in the
+ // block.
+ Assert(BB->getFirstNonPHI() == &TPI,
+ "TerminatePadInst not the first non-PHI instruction in the block.",
+ &TPI);
+
+ if (BasicBlock *UnwindDest = TPI.getUnwindDest()) {
+ Instruction *I = UnwindDest->getFirstNonPHI();
+ Assert(I->isEHPad() && !isa<LandingPadInst>(I),
+ "TerminatePadInst must unwind to an EH block which is not a "
+ "landingpad.",
+ &TPI);
+ }
+
+ visitTerminatorInst(TPI);
+}
+