[WinEH] Verify catchswitch handlers
[oota-llvm.git] / test / Verifier / invalid-eh.ll
1 ; RUN: sed -e s/.T1:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s
2 ; RUN: sed -e s/.T2:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s
3 ; RUN: sed -e s/.T3:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s
4 ; RUN: sed -e s/.T4:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK4 %s
5 ; RUN: sed -e s/.T5:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK5 %s
6 ; RUN: sed -e s/.T6:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK6 %s
7 ; RUN: sed -e s/.T7:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK7 %s
8 ; RUN: sed -e s/.T8:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s
9
10 declare void @g()
11
12 ;T1: define void @f() {
13 ;T1:   entry:
14 ;T1:     catchret from undef to label %next
15 ;T1:     ; CHECK1: CatchReturnInst needs to be provided a CatchPad
16 ;T1:   next:
17 ;T1:     unreachable
18 ;T1: }
19
20 ;T2: define void @f() {
21 ;T2:   entry:
22 ;T2:     %x = cleanuppad within none []
23 ;T2:     ; catchret's first operand's operator must be catchpad
24 ;T2:     catchret from %x to label %entry
25 ;T2:     ; CHECK2: CatchReturnInst needs to be provided a CatchPad
26 ;T2: }
27
28 ;T3: define void @f() {
29 ;T3:   entry:
30 ;T3:     cleanupret from undef unwind label %next
31 ;T3:     ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
32 ;T3:   next:
33 ;T3:     unreachable
34 ;T3: }
35
36 ;T4: define void @f() {
37 ;T4:   entry:
38 ;T4:     %cs = catchswitch within none [label %next] unwind to caller
39 ;T4:   next:
40 ;T4:     %x = catchpad within %cs []
41 ;T4:     ; cleanupret first operand's operator must be cleanuppad
42 ;T4:     cleanupret from %x unwind to caller
43 ;T4:     ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad
44 ;T4: }
45
46 ;T5: define void @f() personality void ()* @g {
47 ;T5:   entry:
48 ;T5:     ret void
49 ;T5:   switch:
50 ;T5:     %cs = catchswitch within none [label %catch] unwind to caller
51 ;T5:   catch:
52 ;T5:     catchpad within %cs []
53 ;T5:     unreachable
54 ;T5:   bogus:
55 ;T5:     cleanuppad within %cs []
56 ;T5:     ; CHECK5: CleanupPadInst has an invalid parent
57 ;T5:     unreachable
58 ;T5: }
59
60 ;T6: define void @f() personality void ()* @g {
61 ;T6:   entry:
62 ;T6:     ret void
63 ;T6:   switch1:
64 ;T6:     %cs1 = catchswitch within none [label %catch1] unwind label %catch2
65 ;T6:     ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch
66 ;T6:   catch1:
67 ;T6:     catchpad within %cs1 []
68 ;T6:     unreachable
69 ;T6:   switch2:
70 ;T6:     %cs2 = catchswitch within none [label %catch2] unwind to caller
71 ;T6:   catch2:
72 ;T6:     catchpad within %cs2 []
73 ;T6:     unreachable
74 ;T6: }
75
76 ;T7: define void @f() personality void ()* @g {
77 ;T7:   entry:
78 ;T7:     ret void
79 ;T7:   switch1:
80 ;T7:     %cs1 = catchswitch within none [label %catch1] unwind to caller
81 ;T7:   catch1:
82 ;T7:     catchpad within %cs1 []
83 ;T7:     unreachable
84 ;T7:   switch2:
85 ;T7:     %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
86 ;T7:     ; CHECK7: CatchSwitchInst has an invalid parent
87 ;T7:   catch2:
88 ;T7:     catchpad within %cs2 []
89 ;T7:     unreachable
90 ;T7: }
91
92 ;T8: define void @f() personality void ()* @g {
93 ;T8:   entry:
94 ;T8:     ret void
95 ;T8:   switch1:
96 ;T8:     %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
97 ;T8:     ; CHECK8: CatchSwitchInst handlers must be catchpads
98 ;T8: }