[llvm] r262268 - [Verifier] Handle more funclet edge cases
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 29 14:56:37 PST 2016
Author: majnemer
Date: Mon Feb 29 16:56:36 2016
New Revision: 262268
URL: http://llvm.org/viewvc/llvm-project?rev=262268&view=rev
Log:
[Verifier] Handle more funclet edge cases
This change makes the verifier a little more paranoid. It was possible
to trick the verifier into crashing or infinite looping.
Modified:
llvm/trunk/lib/IR/Verifier.cpp
llvm/trunk/test/Verifier/invalid-eh.ll
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=262268&r1=262267&r2=262268&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon Feb 29 16:56:36 2016
@@ -3119,8 +3119,6 @@ void Verifier::visitLandingPadInst(Landi
}
void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
- visitEHPadPredecessors(CPI);
-
BasicBlock *BB = CPI.getParent();
Function *F = BB->getParent();
@@ -3136,6 +3134,7 @@ void Verifier::visitCatchPadInst(CatchPa
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(Catc
}
void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) {
- visitEHPadPredecessors(CPI);
-
BasicBlock *BB = CPI.getParent();
Function *F = BB->getParent();
@@ -3166,6 +3163,7 @@ void Verifier::visitCleanupPadInst(Clean
Assert(isa<ConstantTokenNone>(ParentPad) || isa<FuncletPadInst>(ParentPad),
"CleanupPadInst has an invalid parent.", &CPI);
+ visitEHPadPredecessors(CPI);
visitFuncletPadInst(CPI);
}
@@ -3173,8 +3171,12 @@ void Verifier::visitFuncletPadInst(Funcl
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(Funcl
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(Funcl
}
void Verifier::visitCatchSwitchInst(CatchSwitchInst &CatchSwitch) {
- visitEHPadPredecessors(CatchSwitch);
-
BasicBlock *BB = CatchSwitch.getParent();
Function *F = BB->getParent();
@@ -3362,6 +3364,7 @@ void Verifier::visitCatchSwitchInst(Catc
"CatchSwitchInst handlers must be catchpads", &CatchSwitch, Handler);
}
+ visitEHPadPredecessors(CatchSwitch);
visitTerminatorInst(CatchSwitch);
}
Modified: llvm/trunk/test/Verifier/invalid-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/invalid-eh.ll?rev=262268&r1=262267&r2=262268&view=diff
==============================================================================
--- llvm/trunk/test/Verifier/invalid-eh.ll (original)
+++ llvm/trunk/test/Verifier/invalid-eh.ll Mon Feb 29 16:56:36 2016
@@ -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: }
More information about the llvm-commits
mailing list