diff options
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 75 |
2 files changed, 76 insertions, 1 deletions
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 124bf089321..2b09e551b79 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -469,6 +469,8 @@ bool Instruction::mayThrow() const { return CRI->unwindsToCaller(); if (const auto *CEBI = dyn_cast<CatchEndBlockInst>(this)) return CEBI->unwindsToCaller(); + if (const auto *TBI = dyn_cast<TerminateBlockInst>(this)) + return TBI->unwindsToCaller(); return isa<ResumeInst>(this); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index cc7d662d759..6def326a618 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -184,6 +184,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { /// \brief Track unresolved string-based type references. SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs; + /// \brief The result value from the personality function. + Type *PersonalityFnResultTy; + /// \brief Whether we've seen a call to @llvm.localescape in this function /// already. bool SawFrameEscape; @@ -194,7 +197,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { public: explicit Verifier(raw_ostream &OS) - : VerifierSupport(OS), Context(nullptr), SawFrameEscape(false) {} + : VerifierSupport(OS), Context(nullptr), PersonalityFnResultTy(nullptr), + SawFrameEscape(false) {} bool verify(const Function &F) { M = F.getParent(); @@ -228,6 +232,7 @@ public: // FIXME: We strip const here because the inst visitor strips const. visit(const_cast<Function &>(F)); InstsInThisBlock.clear(); + PersonalityFnResultTy = nullptr; SawFrameEscape = false; return !Broken; @@ -383,6 +388,7 @@ private: void visitCatchBlockInst(CatchBlockInst &CBI); void visitCatchEndBlockInst(CatchEndBlockInst &CEBI); void visitCleanupBlockInst(CleanupBlockInst &CBI); + void visitCleanupReturnInst(CleanupReturnInst &CRI); void visitTerminateBlockInst(TerminateBlockInst &TBI); void VerifyCallSite(CallSite CS); @@ -2799,6 +2805,14 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { &LPI); } + if (!PersonalityFnResultTy) + PersonalityFnResultTy = LPI.getType(); + else + Assert(PersonalityFnResultTy == LPI.getType(), + "The personality routine should have a consistent result type " + "inside a function.", + &LPI); + Function *F = LPI.getParent()->getParent(); Assert(F->hasPersonalityFn(), "LandingPadInst needs to be in a function with a personality.", &LPI); @@ -2827,6 +2841,14 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { void Verifier::visitCatchBlockInst(CatchBlockInst &CBI) { BasicBlock *BB = CBI.getParent(); + if (!PersonalityFnResultTy) + PersonalityFnResultTy = CBI.getType(); + else + Assert(PersonalityFnResultTy == CBI.getType(), + "The personality routine should have a consistent result type " + "inside a function.", + &CBI); + Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), "CatchBlockInst needs to be in a function with a personality.", &CBI); @@ -2837,6 +2859,12 @@ void Verifier::visitCatchBlockInst(CatchBlockInst &CBI) { "CatchBlockInst not the first non-PHI instruction in the block.", &CBI); + BasicBlock *UnwindDest = CBI.getUnwindDest(); + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert(I->isEHBlock() && !isa<LandingPadInst>(I), + "CatchBlockInst must unwind to an EH block which is not a landingpad.", + &CBI); + visitTerminatorInst(CBI); } @@ -2854,12 +2882,37 @@ void Verifier::visitCatchEndBlockInst(CatchEndBlockInst &CEBI) { "CatchEndBlockInst not the first non-PHI instruction in the block.", &CEBI); + unsigned CatchBlocksSeen = 0; + for (BasicBlock *PredBB : predecessors(BB)) + if (isa<CatchBlockInst>(PredBB->getTerminator())) + ++CatchBlocksSeen; + + Assert(CatchBlocksSeen <= 1, "CatchEndBlockInst must have no more than one " + "CatchBlockInst predecessor.", + &CEBI); + + if (BasicBlock *UnwindDest = CEBI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert( + I->isEHBlock() && !isa<LandingPadInst>(I), + "CatchEndBlock must unwind to an EH block which is not a landingpad.", + &CEBI); + } + visitTerminatorInst(CEBI); } void Verifier::visitCleanupBlockInst(CleanupBlockInst &CBI) { BasicBlock *BB = CBI.getParent(); + if (!PersonalityFnResultTy) + PersonalityFnResultTy = CBI.getType(); + else + Assert(PersonalityFnResultTy == CBI.getType(), + "The personality routine should have a consistent result type " + "inside a function.", + &CBI); + Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), "CleanupBlockInst needs to be in a function with a personality.", &CBI); @@ -2873,6 +2926,18 @@ void Verifier::visitCleanupBlockInst(CleanupBlockInst &CBI) { visitInstruction(CBI); } +void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) { + if (BasicBlock *UnwindDest = CRI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert(I->isEHBlock() && !isa<LandingPadInst>(I), + "CleanupReturnInst must unwind to an EH block which is not a " + "landingpad.", + &CRI); + } + + visitTerminatorInst(CRI); +} + void Verifier::visitTerminateBlockInst(TerminateBlockInst &TBI) { BasicBlock *BB = TBI.getParent(); @@ -2887,6 +2952,14 @@ void Verifier::visitTerminateBlockInst(TerminateBlockInst &TBI) { "TerminateBlockInst not the first non-PHI instruction in the block.", &TBI); + if (BasicBlock *UnwindDest = TBI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert(I->isEHBlock() && !isa<LandingPadInst>(I), + "TerminateBlockInst must unwind to an EH block which is not a " + "landingpad.", + &TBI); + } + visitTerminatorInst(TBI); } |