[WinEH] Fix catchpad pred verification
authorJoseph Tremoulet <jotrem@microsoft.com>
Sun, 10 Jan 2016 04:32:03 +0000 (04:32 +0000)
committerJoseph Tremoulet <jotrem@microsoft.com>
Sun, 10 Jan 2016 04:32:03 +0000 (04:32 +0000)
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
test/Verifier/invalid-eh.ll

index a99927065d0e7ee7e00365a995a86ad81ba008a1..9198b0e1fb587f4df09dd5c64ace9e647757e0c5 100644 (file)
@@ -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;
   }
 
index af3d987a39b55b28588f163dca7b51cd97578d71..0f27198af536c4a9edb523f752fb00e4e79b77a0 100644 (file)
@@ -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: }