about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/interpret/eval_context.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-12 10:19:42 +0000
committerbors <bors@rust-lang.org>2023-07-12 10:19:42 +0000
commit136dab66142115d9de16b4cfe2d8395d71a8ab6d (patch)
tree966cbfd788c367b9efe03e40625b4645fec5cc7c /compiler/rustc_const_eval/src/interpret/eval_context.rs
parent910be1b3e83d8876a144441695b7a5077967296e (diff)
parente7c6db7d44b8627b9b3b1106fc08413c52fbabaa (diff)
downloadrust-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.rs8
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