[Verifier] Diagnose when unwinding out of cycles of blocks

Generally speaking, this can only happen with unreachable code.
However, neglecting to check for this condition would lead us to loop
forever.

llvm-svn: 262284
This commit is contained in:
David Majnemer 2016-03-01 01:19:05 +00:00
parent 4834994813
commit 54603e7ab8
2 changed files with 23 additions and 1 deletions

View File

@ -3064,6 +3064,7 @@ void Verifier::visitEHPadPredecessors(Instruction &I) {
}
// The edge may exit from zero or more nested pads.
SmallSet<Value *, 8> Seen;
for (;; FromPad = getParentPad(FromPad)) {
Assert(FromPad != ToPad,
"EH pad cannot handle exceptions raised within it", FromPad, TI);
@ -3073,6 +3074,8 @@ void Verifier::visitEHPadPredecessors(Instruction &I) {
}
Assert(!isa<ConstantTokenNone>(FromPad),
"A single unwind edge may only enter one EH pad", TI);
Assert(Seen.insert(FromPad).second,
"EH pad jumps through a cycle of pads", FromPad);
}
}
}
@ -3171,7 +3174,7 @@ void Verifier::visitFuncletPadInst(FuncletPadInst &FPI) {
User *FirstUser = nullptr;
Value *FirstUnwindPad = nullptr;
SmallVector<FuncletPadInst *, 8> Worklist({&FPI});
std::set<FuncletPadInst *> Seen;
SmallSet<FuncletPadInst *, 8> Seen;
while (!Worklist.empty()) {
FuncletPadInst *CurrentPad = Worklist.pop_back_val();

View File

@ -22,6 +22,7 @@
; 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
; RUN: sed -e s/.T25:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK25 %s
declare void @g()
@ -420,3 +421,21 @@ declare void @g()
;T24: exit:
;T24: unreachable
;T24: }
;T25: define void @f() personality void ()* @g {
;T25: entry:
;T25: unreachable
;T25:
;T25: catch.dispatch:
;T25: %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
;T25: ; CHECK25: EH pad jumps through a cycle of pads
;T25: ; CHECK25: %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
;T25:
;T25: catch:
;T25: %cp2 = catchpad within %cs [i8* null, i32 64, i8* null]
;T25: unreachable
;T25:
;T25: ehcleanup:
;T25: %cp3 = cleanuppad within none []
;T25: cleanupret from %cp3 unwind to caller
;T25: }