@@ -17,7 +17,7 @@ use super::{
1717} ;
1818
1919impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
20- pub ( super ) fn fn_can_unwind ( & self , attrs : CodegenFnAttrFlags , abi : Abi ) -> bool {
20+ fn fn_can_unwind ( & self , attrs : CodegenFnAttrFlags , abi : Abi ) -> bool {
2121 layout:: fn_can_unwind (
2222 self . tcx . sess . panic_strategy ( ) ,
2323 attrs,
@@ -247,37 +247,38 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
247247 }
248248 } ;
249249
250+ let get_abi = |this : & Self , instance_ty : Ty < ' tcx > | match instance_ty. kind ( ) {
251+ ty:: FnDef ( ..) => instance_ty. fn_sig ( * this. tcx ) . abi ( ) ,
252+ ty:: Closure ( ..) => Abi :: RustCall ,
253+ ty:: Generator ( ..) => Abi :: Rust ,
254+ _ => span_bug ! ( this. cur_span( ) , "unexpected callee ty: {:?}" , instance_ty) ,
255+ } ;
256+
250257 // ABI check
251- let check_abi = |this : & Self , instance_ty : Ty < ' tcx > | -> InterpResult < ' tcx > {
252- if M :: enforce_abi ( this) {
253- let callee_abi = match instance_ty. kind ( ) {
254- ty:: FnDef ( ..) => instance_ty. fn_sig ( * this. tcx ) . abi ( ) ,
255- ty:: Closure ( ..) => Abi :: RustCall ,
256- ty:: Generator ( ..) => Abi :: Rust ,
257- _ => span_bug ! ( this. cur_span( ) , "unexpected callee ty: {:?}" , instance_ty) ,
258- } ;
259- let normalize_abi = |abi| match abi {
260- Abi :: Rust | Abi :: RustCall | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic =>
261- // These are all the same ABI, really.
262- {
263- Abi :: Rust
264- }
265- abi => abi,
266- } ;
267- if normalize_abi ( caller_abi) != normalize_abi ( callee_abi) {
268- throw_ub_format ! (
269- "calling a function with ABI {} using caller ABI {}" ,
270- callee_abi. name( ) ,
271- caller_abi. name( )
272- )
258+ let check_abi = |callee_abi : Abi | -> InterpResult < ' tcx > {
259+ let normalize_abi = |abi| match abi {
260+ Abi :: Rust | Abi :: RustCall | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic =>
261+ // These are all the same ABI, really.
262+ {
263+ Abi :: Rust
273264 }
265+ abi => abi,
266+ } ;
267+ if normalize_abi ( caller_abi) != normalize_abi ( callee_abi) {
268+ throw_ub_format ! (
269+ "calling a function with ABI {} using caller ABI {}" ,
270+ callee_abi. name( ) ,
271+ caller_abi. name( )
272+ )
274273 }
275274 Ok ( ( ) )
276275 } ;
277276
278277 match instance. def {
279278 ty:: InstanceDef :: Intrinsic ( ..) => {
280- check_abi ( self , instance. ty ( * self . tcx , self . param_env ) ) ?;
279+ if M :: enforce_abi ( self ) {
280+ check_abi ( get_abi ( self , instance. ty ( * self . tcx , self . param_env ) ) ) ?;
281+ }
281282 assert ! ( caller_abi == Abi :: RustIntrinsic || caller_abi == Abi :: PlatformIntrinsic ) ;
282283 M :: call_intrinsic ( self , instance, args, ret, unwind)
283284 }
@@ -298,15 +299,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
298299 // Check against the ABI of the MIR body we are calling (not the ABI of `instance`;
299300 // these can differ when `find_mir_or_eval_fn` does something clever like resolve
300301 // exported symbol names).
301- check_abi ( self , self . tcx . type_of ( body. source . def_id ( ) ) ) ?;
302+ let callee_def_id = body. source . def_id ( ) ;
303+ let callee_abi = get_abi ( self , self . tcx . type_of ( callee_def_id) ) ;
304+
305+ if M :: enforce_abi ( self ) {
306+ check_abi ( callee_abi) ?;
307+ }
308+
309+ let callee_can_unwind =
310+ self . fn_can_unwind ( self . tcx . codegen_fn_attrs ( callee_def_id) . flags , callee_abi) ;
302311
303312 self . push_stack_frame (
304313 instance,
305314 body,
306315 ret. map ( |p| p. 0 ) ,
307316 StackPopCleanup :: Goto {
308317 ret : ret. map ( |p| p. 1 ) ,
309- unwind : if can_unwind {
318+ unwind : if can_unwind && callee_can_unwind {
310319 StackPopUnwind :: Cleanup ( unwind)
311320 } else {
312321 StackPopUnwind :: NotAllowed
0 commit comments