diff options
| -rw-r--r-- | llvm/lib/IR/Verifier.cpp | 15 | ||||
| -rw-r--r-- | llvm/test/Verifier/invalid-eh.ll | 50 |
2 files changed, 59 insertions, 6 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index f02879eeb5b..8367a2702eb 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3119,8 +3119,6 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { } void Verifier::visitCatchPadInst(CatchPadInst &CPI) { - visitEHPadPredecessors(CPI); - BasicBlock *BB = CPI.getParent(); Function *F = BB->getParent(); @@ -3136,6 +3134,7 @@ void Verifier::visitCatchPadInst(CatchPadInst &CPI) { Assert(BB->getFirstNonPHI() == &CPI, "CatchPadInst not the first non-PHI instruction in the block.", &CPI); + visitEHPadPredecessors(CPI); visitFuncletPadInst(CPI); } @@ -3148,8 +3147,6 @@ void Verifier::visitCatchReturnInst(CatchReturnInst &CatchReturn) { } void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { - visitEHPadPredecessors(CPI); - BasicBlock *BB = CPI.getParent(); Function *F = BB->getParent(); @@ -3166,6 +3163,7 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { Assert(isa<ConstantTokenNone>(ParentPad) || isa<FuncletPadInst>(ParentPad), "CleanupPadInst has an invalid parent.", &CPI); + visitEHPadPredecessors(CPI); visitFuncletPadInst(CPI); } @@ -3173,8 +3171,12 @@ void Verifier::visitFuncletPadInst(FuncletPadInst &FPI) { User *FirstUser = nullptr; Value *FirstUnwindPad = nullptr; SmallVector<FuncletPadInst *, 8> Worklist({&FPI}); + std::set<FuncletPadInst *> Seen; + while (!Worklist.empty()) { FuncletPadInst *CurrentPad = Worklist.pop_back_val(); + Assert(Seen.insert(CurrentPad).second, + "FuncletPadInst must not be nested within itself", CurrentPad); Value *UnresolvedAncestorPad = nullptr; for (User *U : CurrentPad->users()) { BasicBlock *UnwindDest; @@ -3210,6 +3212,8 @@ void Verifier::visitFuncletPadInst(FuncletPadInst &FPI) { bool ExitsFPI; if (UnwindDest) { UnwindPad = UnwindDest->getFirstNonPHI(); + if (!cast<Instruction>(UnwindPad)->isEHPad()) + continue; Value *UnwindParent = getParentPad(UnwindPad); // Ignore unwind edges that don't exit CurrentPad. if (UnwindParent == CurrentPad) @@ -3323,8 +3327,6 @@ void Verifier::visitFuncletPadInst(FuncletPadInst &FPI) { } void Verifier::visitCatchSwitchInst(CatchSwitchInst &CatchSwitch) { - visitEHPadPredecessors(CatchSwitch); - BasicBlock *BB = CatchSwitch.getParent(); Function *F = BB->getParent(); @@ -3362,6 +3364,7 @@ void Verifier::visitCatchSwitchInst(CatchSwitchInst &CatchSwitch) { "CatchSwitchInst handlers must be catchpads", &CatchSwitch, Handler); } + visitEHPadPredecessors(CatchSwitch); visitTerminatorInst(CatchSwitch); } diff --git a/llvm/test/Verifier/invalid-eh.ll b/llvm/test/Verifier/invalid-eh.ll index 0f27198af53..f94e3a6d1cb 100644 --- a/llvm/test/Verifier/invalid-eh.ll +++ b/llvm/test/Verifier/invalid-eh.ll @@ -19,6 +19,9 @@ ; RUN: sed -e s/.T19:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK19 %s ; RUN: sed -e s/.T20:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK20 %s ; RUN: sed -e s/.T21:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK21 %s +; RUN: sed -e s/.T22:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK22 %s +; RUN: sed -e s/.T23:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK23 %s +; RUN: sed -e s/.T24:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK24 %s declare void @g() @@ -370,3 +373,50 @@ declare void @g() ;T21: %cp2 = catchpad within %cs [i32 2] ;T21: unreachable ;T21: } + +;T22: define void @f() personality void ()* @g { +;T22: invoke void @g() +;T22: to label %merge unwind label %cleanup +;T22: +;T22: cleanup: +;T22: %outer = cleanuppad within none [] +;T22: invoke void @g() [ "funclet"(token %outer) ] +;T22: to label %merge unwind label %merge +;T22: ; CHECK22: The unwind destination does not have an exception handling instruction! +;T22: ; CHECK22: invoke void @g() [ "funclet"(token %outer) ] +;T22: ; CHECK22: to label %merge unwind label %merge +;T22: +;T22: merge: +;T22: unreachable +;T22: } + +;T23: define void @f() personality void ()* @g { +;T23: invoke void @g() +;T23: to label %exit unwind label %pad +;T23: +;T23: pad: +;T23: %outer = catchpad within %outer [] +;T23: ; CHECK23: CatchPadInst needs to be directly nested in a CatchSwitchInst. +;T23: ; CHECK23: %outer = catchpad within %outer [] +;T23: unreachable +;T23: +;T23: exit: +;T23: unreachable +;T23: } + +;T24: define void @f() personality void ()* @g { +;T24: invoke void @g() +;T24: to label %exit unwind label %pad +;T24: ; CHECK24: A single unwind edge may only enter one EH pad +;T24: ; CHECK24: invoke void @g() +;T24: ; CHECK24: to label %exit unwind label %pad +;T24: +;T24: pad: +;T24: %outer = cleanuppad within %outer [] +;T24: ; CHECK24: FuncletPadInst must not be nested within itself +;T24: ; CHECK24: %outer = cleanuppad within %outer [] +;T24: unreachable +;T24: +;T24: exit: +;T24: unreachable +;T24: } |

