From 8ef397400707e3c11424c8a1aa6bc9302617a138 Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Sun, 23 May 2021 04:37:17 +0800 Subject: [PATCH] Pass `StackPopUnwind` to `eval_fn_call()` and some other functions that are called by `eval_fn_call()` --- compiler/rustc_mir/src/const_eval/machine.rs | 6 ++-- compiler/rustc_mir/src/interpret/machine.rs | 10 +++--- .../rustc_mir/src/interpret/terminator.rs | 36 ++++++++++--------- .../rustc_mir/src/transform/const_prop.rs | 5 +-- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index 8e9148f5b66..773df7d7b60 100644 --- a/compiler/rustc_mir/src/const_eval/machine.rs +++ b/compiler/rustc_mir/src/const_eval/machine.rs @@ -17,7 +17,7 @@ use rustc_target::spec::abi::Abi; use crate::interpret::{ self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, InterpCx, InterpResult, Memory, - OpTy, PlaceTy, Pointer, Scalar, + OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind, }; use super::error::*; @@ -223,7 +223,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _abi: Abi, args: &[OpTy<'tcx>], _ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, - _unwind: Option, // unwinding is not supported in consts + _unwind: StackPopUnwind, // unwinding is not supported in consts ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> { debug!("find_mir_or_eval_fn: {:?}", instance); @@ -263,7 +263,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, - _unwind: Option, + _unwind: StackPopUnwind, ) -> InterpResult<'tcx> { // Shared intrinsics. if ecx.emulate_intrinsic(instance, args, ret)? { diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs index 0ca99da7304..0d01dc3c219 100644 --- a/compiler/rustc_mir/src/interpret/machine.rs +++ b/compiler/rustc_mir/src/interpret/machine.rs @@ -14,7 +14,7 @@ use rustc_target::spec::abi::Abi; use super::{ AllocId, Allocation, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult, LocalValue, - MemPlace, Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar, + MemPlace, Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar, StackPopUnwind, }; /// Data returned by Machine::stack_pop, @@ -163,7 +163,7 @@ pub trait Machine<'mir, 'tcx>: Sized { abi: Abi, args: &[OpTy<'tcx, Self::PointerTag>], ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, - unwind: Option, + unwind: StackPopUnwind, ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>; /// Execute `fn_val`. It is the hook's responsibility to advance the instruction @@ -174,7 +174,7 @@ pub trait Machine<'mir, 'tcx>: Sized { abi: Abi, args: &[OpTy<'tcx, Self::PointerTag>], ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, - unwind: Option, + unwind: StackPopUnwind, ) -> InterpResult<'tcx>; /// Directly process an intrinsic without pushing a stack frame. It is the hook's @@ -184,7 +184,7 @@ pub trait Machine<'mir, 'tcx>: Sized { instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, - unwind: Option, + unwind: StackPopUnwind, ) -> InterpResult<'tcx>; /// Called to evaluate `Assert` MIR terminators that trigger a panic. @@ -456,7 +456,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { _abi: Abi, _args: &[OpTy<$tcx>], _ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>, - _unwind: Option, + _unwind: StackPopUnwind, ) -> InterpResult<$tcx> { match fn_val {} } diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs index 27b2716c5bd..cefd47d718f 100644 --- a/compiler/rustc_mir/src/interpret/terminator.rs +++ b/compiler/rustc_mir/src/interpret/terminator.rs @@ -105,7 +105,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } None => None, }; - self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup, can_unwind)?; + self.eval_fn_call( + fn_val, + abi, + &args[..], + ret, + if can_unwind { + cleanup.map_or(StackPopUnwind::Skip, StackPopUnwind::Cleanup) + } else { + StackPopUnwind::NotAllowed + }, + )?; // Sanity-check that `eval_fn_call` either pushed a new frame or // did a jump to another block. if self.frame_idx() == old_stack && self.frame().loc == old_loc { @@ -235,8 +245,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_abi: Abi, args: &[OpTy<'tcx, M::PointerTag>], ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, - unwind: Option, - can_unwind: bool, + mut unwind: StackPopUnwind, ) -> InterpResult<'tcx> { trace!("eval_fn_call: {:#?}", fn_val); @@ -306,22 +315,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { check_abi(callee_abi)?; } - let can_unwind = can_unwind + if !matches!(unwind, StackPopUnwind::NotAllowed) && self - .fn_can_unwind(self.tcx.codegen_fn_attrs(callee_def_id).flags, callee_abi); + .fn_can_unwind(self.tcx.codegen_fn_attrs(callee_def_id).flags, callee_abi) + { + unwind = StackPopUnwind::NotAllowed; + } self.push_stack_frame( instance, body, ret.map(|p| p.0), - StackPopCleanup::Goto { - ret: ret.map(|p| p.1), - unwind: match (unwind, can_unwind) { - (Some(unwind), true) => StackPopUnwind::Cleanup(unwind), - (None, true) => StackPopUnwind::Skip, - (_, false) => StackPopUnwind::NotAllowed, - }, - }, + StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind }, )?; // If an error is raised here, pop the frame again to get an accurate backtrace. @@ -466,7 +471,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { OpTy::from(ImmTy::from_immediate(receiver_place.ptr.into(), this_receiver_ptr)); trace!("Patched self operand to {:#?}", args[0]); // recurse with concrete function - self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind, can_unwind) + self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind) } } } @@ -505,8 +510,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Abi::Rust, &[arg.into()], Some((&dest.into(), target)), - unwind, - true, + unwind.map_or(StackPopUnwind::Skip, StackPopUnwind::Cleanup), ) } } diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 5968bbbfca7..681d63c6fc9 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -33,6 +33,7 @@ use crate::interpret::{ self, compile_time_machine, AllocId, Allocation, ConstValue, CtfeValidationMode, Frame, ImmTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemPlace, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer, Scalar, ScalarMaybeUninit, StackPopCleanup, + StackPopUnwind, }; use crate::transform::MirPass; @@ -198,7 +199,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> _abi: Abi, _args: &[OpTy<'tcx>], _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, - _unwind: Option, + _unwind: StackPopUnwind, ) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> { Ok(None) } @@ -208,7 +209,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> _instance: ty::Instance<'tcx>, _args: &[OpTy<'tcx>], _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, - _unwind: Option, + _unwind: StackPopUnwind, ) -> InterpResult<'tcx> { throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp") }