forked from OSchip/llvm-project
[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:
parent
e5ec0623d1
commit
f08579f5a8
|
@ -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();
|
||||
|
|
|
@ -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: }
|
||||
|
|
Loading…
Reference in New Issue