@@ -128,19 +128,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
128
128
129
129
let debugloc = DebugLoc :: None ;
130
130
let attrs = attributes:: from_fn_type ( bcx. ccx ( ) , callee. ty ) ;
131
- match * targets {
132
- mir:: CallTargets :: Return ( ret) => {
133
- let llret = build:: Call ( bcx,
134
- callee. immediate ( ) ,
135
- & llargs[ ..] ,
136
- Some ( attrs) ,
137
- debugloc) ;
138
- if !return_outptr && !common:: type_is_zero_size ( bcx. ccx ( ) , ret_ty) {
139
- base:: store_ty ( bcx, llret, call_dest. llval , ret_ty) ;
140
- }
141
- build:: Br ( bcx, self . llblock ( ret) , debugloc)
142
- }
143
- mir:: CallTargets :: WithCleanup ( ( ret, cleanup) ) => {
131
+ match ( * targets, base:: avoid_invoke ( bcx) ) {
132
+ ( mir:: CallTargets :: WithCleanup ( ( ret, cleanup) ) , false ) => {
133
+ let cleanup = self . bcx ( cleanup) ;
144
134
let landingpad = self . make_landing_pad ( cleanup) ;
145
135
build:: Invoke ( bcx,
146
136
callee. immediate ( ) ,
@@ -153,6 +143,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
153
143
// FIXME: What do we do here?
154
144
unimplemented ! ( )
155
145
}
146
+ } ,
147
+ ( t, _) => {
148
+ let ret = match t {
149
+ mir:: CallTargets :: Return ( ret) => ret,
150
+ mir:: CallTargets :: WithCleanup ( ( ret, _) ) => {
151
+ // make a landing pad regardless (so it sets the personality slot.
152
+ let block = self . unreachable_block ( ) ;
153
+ self . make_landing_pad ( block) ;
154
+ ret
155
+ }
156
+ } ;
157
+ let llret = build:: Call ( bcx,
158
+ callee. immediate ( ) ,
159
+ & llargs[ ..] ,
160
+ Some ( attrs) ,
161
+ debugloc) ;
162
+ if !return_outptr && !common:: type_is_zero_size ( bcx. ccx ( ) , ret_ty) {
163
+ base:: store_ty ( bcx, llret, call_dest. llval , ret_ty) ;
164
+ }
165
+ build:: Br ( bcx, self . llblock ( ret) , debugloc)
156
166
}
157
167
}
158
168
} ,
@@ -171,12 +181,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
171
181
}
172
182
let debugloc = DebugLoc :: None ;
173
183
let attrs = attributes:: from_fn_type ( bcx. ccx ( ) , callee. ty ) ;
174
- match * cleanup {
175
- None => {
176
- build:: Call ( bcx, callee. immediate ( ) , & llargs[ ..] , Some ( attrs) , debugloc) ;
177
- build:: Unreachable ( bcx) ;
178
- }
179
- Some ( cleanup) => {
184
+ match ( * cleanup, base:: avoid_invoke ( bcx) ) {
185
+ ( Some ( cleanup) , false ) => {
186
+ let cleanup = self . bcx ( cleanup) ;
180
187
let landingpad = self . make_landing_pad ( cleanup) ;
181
188
let unreachable = self . unreachable_block ( ) ;
182
189
build:: Invoke ( bcx,
@@ -187,13 +194,22 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
187
194
Some ( attrs) ,
188
195
debugloc) ;
189
196
}
197
+ ( t, _) => {
198
+ if t. is_some ( ) {
199
+ // make a landing pad regardless, so it sets the personality slot.
200
+ let block = self . unreachable_block ( ) ;
201
+ self . make_landing_pad ( block) ;
202
+ }
203
+ build:: Call ( bcx, callee. immediate ( ) , & llargs[ ..] , Some ( attrs) , debugloc) ;
204
+ build:: Unreachable ( bcx) ;
205
+ }
190
206
}
191
207
}
192
208
}
193
209
}
194
210
195
- fn make_landing_pad ( & mut self , cleanup : mir :: BasicBlock ) -> Block < ' bcx , ' tcx > {
196
- let bcx = self . bcx ( cleanup) . fcx . new_block ( true , "cleanup" , None ) ;
211
+ fn make_landing_pad ( & mut self , cleanup : Block < ' bcx , ' tcx > ) -> Block < ' bcx , ' tcx > {
212
+ let bcx = cleanup. fcx . new_block ( true , "cleanup" , None ) ;
197
213
let ccx = bcx. ccx ( ) ;
198
214
let llpersonality = bcx. fcx . eh_personality ( ) ;
199
215
let llretty = Type :: struct_ ( ccx, & [ Type :: i8p ( ccx) , Type :: i32 ( ccx) ] , false ) ;
@@ -208,7 +224,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
208
224
build:: Store ( bcx, llretval, personalityslot)
209
225
}
210
226
} ;
211
- build:: Br ( bcx, self . llblock ( cleanup) , DebugLoc :: None ) ;
227
+ build:: Br ( bcx, cleanup. llbb , DebugLoc :: None ) ;
212
228
bcx
213
229
}
214
230
0 commit comments