diff options
| author | bors <bors@rust-lang.org> | 2023-07-12 10:19:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-07-12 10:19:42 +0000 |
| commit | 136dab66142115d9de16b4cfe2d8395d71a8ab6d (patch) | |
| tree | 966cbfd788c367b9efe03e40625b4645fec5cc7c /compiler/rustc_const_eval/src/interpret/eval_context.rs | |
| parent | 910be1b3e83d8876a144441695b7a5077967296e (diff) | |
| parent | e7c6db7d44b8627b9b3b1106fc08413c52fbabaa (diff) | |
| download | rust-136dab66142115d9de16b4cfe2d8395d71a8ab6d.tar.gz rust-136dab66142115d9de16b4cfe2d8395d71a8ab6d.zip | |
Auto merge of #113569 - RalfJung:miri, r=oli-obk
miri: protect Move() function arguments during the call This gives `Move` operands a meaning specific to function calls: - for the duration of the call, the place the operand comes from is protected, making all read and write accesses insta-UB. - the contents of that place are reset to `Uninit`, so looking at them again after the function returns, we cannot observe their contents Turns out we can replace the existing "retag return place" hack with the exact same sort of protection on the return place, which is nicely symmetric. Fixes https://github.com/rust-lang/rust/issues/112564 Fixes https://github.com/rust-lang/miri/issues/2927 This starts with a Miri rustc-push, since we'd otherwise conflict with a PR that recently landed in Miri. (The "miri tree borrows" commit is an unrelated cleanup I noticed while doing the PR. I can remove it if you prefer.) r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret/eval_context.rs')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/eval_context.rs | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 36606ff69a6..5e5ad31d8c2 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -682,11 +682,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { trace!("body: {:#?}", body); - // Clobber previous return place contents, nobody is supposed to be able to see them any more - // This also checks dereferenceable, but not align. We rely on all constructed places being - // sufficiently aligned (in particular we rely on `deref_operand` checking alignment). - self.write_uninit(return_place)?; - // first push a stack frame so we have access to the local substs + // First push a stack frame so we have access to the local substs let pre_frame = Frame { body, loc: Right(body.span), // Span used for errors caused during preamble. @@ -805,6 +801,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub_custom!(fluent::const_eval_unwind_past_top); } + M::before_stack_pop(self, self.frame())?; + // Copy return value. Must of course happen *before* we deallocate the locals. let copy_ret_result = if !unwinding { let op = self |
