Auto merge of #85546 - hyd-dev:unwind, r=RalfJung

const-eval: disallow unwinding across functions that `!fn_can_unwind()`

Following https://github.com/rust-lang/miri/pull/1776#discussion_r633074343, so r? `@RalfJung`

This PR turns `unwind` in `StackPopCleanup::Goto` into a new enum `StackPopUnwind`, with a `NotAllowed` variant to indicate that unwinding is not allowed. This variant is chosen based on `rustc_middle::ty::layout::fn_can_unwind()` in `eval_fn_call()` when pushing the frame. A check is added in `unwind_to_block()` to report UB if unwinding happens across a `StackPopUnwind::NotAllowed` frame.

Tested with Miri `HEAD` with [minor changes](https://github.com/rust-lang/miri/compare/HEAD..9cf3c7f0d86325a586fbcbf2acdc9232b861f1d8) and the rust-lang/miri#1776 branch with [these changes](d866c1c52f..626638fbfe).
This commit is contained in:
bors
2021-05-28 08:49:48 +00:00
7 changed files with 168 additions and 94 deletions

View File

@@ -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<mir::BasicBlock>, // 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<mir::BasicBlock>,
_unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
// Shared intrinsics.
if ecx.emulate_intrinsic(instance, args, ret)? {