From e2fff4f7f9edae5f497b226ace98d95494786a82 Mon Sep 17 00:00:00 2001 From: Joseph Tremoulet Date: Sun, 10 Jan 2016 04:32:03 +0000 Subject: [PATCH] [WinEH] Fix catchpad pred verification Summary: The code was simply ensuring that the catchpad's pred is its catchswitch, which was letting cases slip through where the flow edge was the unwind edge of the catchswitch rather than one of its catch clauses. Reviewers: andrew.w.kaylor, rnk, majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D16011 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257275 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Verifier.cpp | 3 +++ test/Verifier/invalid-eh.ll | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index a99927065d0..9198b0e1fb5 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -2996,6 +2996,9 @@ void Verifier::visitEHPadPredecessors(Instruction &I) { "Block containg CatchPadInst must be jumped to " "only by its catchswitch.", CPI); + Assert(BB != CPI->getCatchSwitch()->getUnwindDest(), + "Catchswitch cannot unwind to one of its catchpads", + CPI->getCatchSwitch(), CPI); return; } diff --git a/test/Verifier/invalid-eh.ll b/test/Verifier/invalid-eh.ll index af3d987a39b..0f27198af53 100644 --- a/test/Verifier/invalid-eh.ll +++ b/test/Verifier/invalid-eh.ll @@ -17,6 +17,8 @@ ; RUN: sed -e s/.T17:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK17 %s ; RUN: sed -e s/.T18:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK18 %s ; 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 declare void @g() @@ -339,3 +341,32 @@ declare void @g() ;T19: unreachable: ;T19: unreachable ;T19: } + +;T20: define void @f() personality void ()* @g { +;T20: entry: +;T20: ret void +;T20: switch: +;T20: %cs = catchswitch within none [label %catch] unwind label %catch +;T20: ; CHECK20: Catchswitch cannot unwind to one of its catchpads +;T20: ; CHECK20-NEXT: %cs = catchswitch within none [label %catch] unwind label %catch +;T20: ; CHECK20-NEXT: %cp = catchpad within %cs [i32 4] +;T20: catch: +;T20: %cp = catchpad within %cs [i32 4] +;T20: unreachable +;T20: } + +;T21: define void @f() personality void ()* @g { +;T21: entry: +;T21: ret void +;T21: switch: +;T21: %cs = catchswitch within none [label %catch1] unwind label %catch2 +;T21: ; CHECK21: Catchswitch cannot unwind to one of its catchpads +;T21: ; CHECK21-NEXT: %cs = catchswitch within none [label %catch1] unwind label %catch2 +;T21: ; CHECK21-NEXT: %cp2 = catchpad within %cs [i32 2] +;T21: catch1: +;T21: %cp1 = catchpad within %cs [i32 1] +;T21: unreachable +;T21: catch2: +;T21: %cp2 = catchpad within %cs [i32 2] +;T21: unreachable +;T21: } -- 2.34.1