summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-02-29 22:56:36 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-02-29 22:56:36 +0000
commitfe2f7f367a09cc5b0330b87c0f0b0078a0700a8f (patch)
treecc40146a7df6c7f1b509d784e4f2e92cc9799622 /llvm/lib/IR/Verifier.cpp
parent83be06e52960e56ed6b7c78d151bbe4dff941a5f (diff)
downloadbcm5719-llvm-fe2f7f367a09cc5b0330b87c0f0b0078a0700a8f.tar.gz
bcm5719-llvm-fe2f7f367a09cc5b0330b87c0f0b0078a0700a8f.zip
[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. llvm-svn: 262268
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp15
1 files changed, 9 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);
}
OpenPOWER on IntegriCloud