From 38249be509101e87ea4ac10951b1b4ce554f1cc0 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 13 Dec 2024 02:00:20 -0800 Subject: [PATCH] Don't retag the `PtrMetadata(&raw const *_n)` in slice indexing --- compiler/rustc_const_eval/src/interpret/step.rs | 11 +++++++++-- compiler/rustc_mir_build/src/build/expr/as_place.rs | 13 +++++++++++-- compiler/rustc_span/src/hygiene.rs | 4 ++++ .../tests/fail/both_borrows/buggy_as_mut_slice.rs | 2 +- .../both_borrows/buggy_as_mut_slice.stack.stderr | 8 ++++---- 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index b61865be6678..f6d2e476738d 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -9,6 +9,7 @@ use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::source_map::Spanned; +use rustc_span::{DesugaringKind, Span}; use rustc_target::callconv::FnAbi; use tracing::{info, instrument, trace}; @@ -80,7 +81,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { use rustc_middle::mir::StatementKind::*; match &stmt.kind { - Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?, + Assign(box (place, rvalue)) => { + self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)? + } SetDiscriminant { place, variant_index } => { let dest = self.eval_place(**place)?; @@ -159,6 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { &mut self, rvalue: &mir::Rvalue<'tcx>, place: mir::Place<'tcx>, + span: Span, ) -> InterpResult<'tcx> { let dest = self.eval_place(place)?; // FIXME: ensure some kind of non-aliasing between LHS and RHS? @@ -250,8 +254,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let src = self.eval_place(place)?; let place = self.force_allocation(&src)?; let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout); - if !place_base_raw { + if !place_base_raw + && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow) + { // If this was not already raw, it needs retagging. + // Unless it's the `PtrMetadata(&raw const *_n)` from indexing. val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?; } self.write_immediate(*val, &dest)?; diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 9f377f792ef3..70a74910a68c 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_middle::{bug, span_bug}; -use rustc_span::Span; +use rustc_span::{DesugaringKind, Span}; use tracing::{debug, instrument, trace}; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; @@ -668,11 +668,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // the MIR we're building here needs to pass NLL later. Operand::Copy(Place::from(place.local)) } else { + let len_span = self.tcx.with_stable_hashing_context(|hcx| { + let span = source_info.span; + span.mark_with_reason( + None, + DesugaringKind::IndexBoundsCheckReborrow, + span.edition(), + hcx, + ) + }); let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty); let slice_ptr = self.temp(ptr_ty, span); self.cfg.push_assign( block, - source_info, + SourceInfo { span: len_span, ..source_info }, slice_ptr, Rvalue::RawPtr(Mutability::Not, place), ); diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index a5826137181d..3cdae437b7d4 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1163,6 +1163,9 @@ pub enum DesugaringKind { WhileLoop, /// `async Fn()` bound modifier BoundModifier, + /// Marks a `&raw const *_1` needed as part of getting the length of a mutable + /// slice for the bounds check, so that MIRI's retag handling can recognize it. + IndexBoundsCheckReborrow, } impl DesugaringKind { @@ -1179,6 +1182,7 @@ impl DesugaringKind { DesugaringKind::ForLoop => "`for` loop", DesugaringKind::WhileLoop => "`while` loop", DesugaringKind::BoundModifier => "trait bound modifier", + DesugaringKind::IndexBoundsCheckReborrow => "slice indexing", } } } diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs index 6027b5c0f5ff..6d535a14c048 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs +++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.rs @@ -13,7 +13,7 @@ fn main() { let v1 = safe::as_mut_slice(&v); let v2 = safe::as_mut_slice(&v); v1[1] = 5; - //~[stack]^ ERROR: /trying to retag .+ for SharedReadOnly permission .+ tag does not exist in the borrow stack for this location/ + //~[stack]^ ERROR: /write access .* tag does not exist in the borrow stack/ v2[1] = 7; //~[tree]^ ERROR: /write access through .* is forbidden/ } diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr index c5488a537a2e..4e5355f5653f 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/buggy_as_mut_slice.stack.stderr @@ -1,11 +1,11 @@ -error: Undefined Behavior: trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x4], but that tag does not exist in the borrow stack for this location --> tests/fail/both_borrows/buggy_as_mut_slice.rs:LL:CC | LL | v1[1] = 5; - | ^^^^^ + | ^^^^^^^^^ | | - | trying to retag from for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - | this error occurs as part of retag at ALLOC[0x0..0xc] + | attempting a write access using at ALLOC[0x4], but that tag does not exist in the borrow stack for this location + | this error occurs as part of an access at ALLOC[0x4..0x8] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information