aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/NaCl/pnacl-eh-exception-info.ll
blob: 478bc97d3f192a21b5961b407378b5c7ef6cacb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
; RUN: opt %s -pnacl-sjlj-eh -S | FileCheck %s

; Example std::type_info objects.
@exc_typeid1 = external global i8
@exc_typeid2 = external global i8
@exc_typeid3 = external global i8

; This must be declared for "-pnacl-sjlj-eh" to work.
@__pnacl_eh_stack = external thread_local global i8*

declare i32 @llvm.eh.typeid.for(i8*)

declare void @external_func()


@__pnacl_eh_type_table = external global i8*
@__pnacl_eh_action_table = external global i8*
@__pnacl_eh_filter_table = external global i8*

; CHECK: %action_table_entry = type { i32, i32 }

; CHECK: @__pnacl_eh_type_table = internal constant [4 x i8*] [i8* @exc_typeid1, i8* @exc_typeid2, i8* @exc_typeid3, i8* null]

; CHECK: @__pnacl_eh_action_table = internal constant [7 x %action_table_entry] [%action_table_entry { i32 3, i32 0 }, %action_table_entry { i32 2, i32 1 }, %action_table_entry { i32 1, i32 2 }, %action_table_entry { i32 -1, i32 0 }, %action_table_entry { i32 -2, i32 0 }, %action_table_entry { i32 4, i32 0 }, %action_table_entry zeroinitializer]

; CHECK: @__pnacl_eh_filter_table = internal constant [5 x i32] [i32 0, i32 2, i32 3, i32 1, i32 0]


; Exception type pointers are allocated IDs which specify the index
; into __pnacl_eh_type_table where the type may be found.
define void @test_eh_typeid(i32 %arg) {
  %id1 = call i32 @llvm.eh.typeid.for(i8* @exc_typeid1)
  %id2 = call i32 @llvm.eh.typeid.for(i8* @exc_typeid2)
  %id3 = call i32 @llvm.eh.typeid.for(i8* @exc_typeid3)
  %cmp1 = icmp eq i32 %arg, %id1
  %cmp2 = icmp eq i32 %arg, %id2
  %cmp3 = icmp eq i32 %arg, %id3
  ret void
}
; CHECK: define void @test_eh_typeid
; CHECK-NEXT: %cmp1 = icmp eq i32 %arg, 1
; CHECK-NEXT: %cmp2 = icmp eq i32 %arg, 2
; CHECK-NEXT: %cmp3 = icmp eq i32 %arg, 3
; CHECK-NEXT: ret void


define void @test_single_catch_clause() {
  invoke void @external_func() to label %cont unwind label %lpad
cont:
  ret void
lpad:
  landingpad i32 personality i8* null
      catch i8* @exc_typeid3
  ret void
}
; CHECK: define void @test_single_catch_clause
; CHECK: store i32 1, i32* %exc_info_ptr


define void @test_multiple_catch_clauses() {
  invoke void @external_func() to label %cont unwind label %lpad
cont:
  ret void
lpad:
  landingpad i32 personality i8* null
      catch i8* @exc_typeid1
      catch i8* @exc_typeid2
      catch i8* @exc_typeid3
  ret void
}
; CHECK: define void @test_multiple_catch_clauses
; CHECK: store i32 3, i32* %exc_info_ptr


define void @test_empty_filter_clause() {
  invoke void @external_func() to label %cont unwind label %lpad
cont:
  ret void
lpad:
  landingpad i32 personality i8* null
      filter [0 x i8*] []
  ret void
}
; CHECK: define void @test_empty_filter_clause
; CHECK: store i32 4, i32* %exc_info_ptr


define void @test_filter_clause() {
  invoke void @external_func() to label %cont unwind label %lpad
cont:
  ret void
lpad:
  landingpad i32 personality i8* null
      filter [3 x i8*] [i8* @exc_typeid2,
                        i8* @exc_typeid3,
                        i8* @exc_typeid1]
  ret void
}
; CHECK: define void @test_filter_clause
; CHECK: store i32 5, i32* %exc_info_ptr


; "catch i8* null" means that any C++ exception matches.
define void @test_catch_all_clause() {
  invoke void @external_func() to label %cont unwind label %lpad
cont:
  ret void
lpad:
  landingpad i32 personality i8* null
      catch i8* null
  ret void
}
; CHECK: define void @test_catch_all_clause
; CHECK: store i32 6, i32* %exc_info_ptr


define void @test_cleanup_clause() {
  invoke void @external_func() to label %cont unwind label %lpad
cont:
  ret void
lpad:
  landingpad i32 personality i8* null
      cleanup
  ret void
}
; CHECK: define void @test_cleanup_clause
; CHECK: store i32 7, i32* %exc_info_ptr