Don't retag the PtrMetadata(&raw const *_n)
in slice indexing
This commit is contained in:
parent
612adbb6bf
commit
38249be509
5 changed files with 29 additions and 9 deletions
|
@ -9,6 +9,7 @@ use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_middle::ty::{self, Instance, Ty};
|
use rustc_middle::ty::{self, Instance, Ty};
|
||||||
use rustc_middle::{bug, mir, span_bug};
|
use rustc_middle::{bug, mir, span_bug};
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
|
use rustc_span::{DesugaringKind, Span};
|
||||||
use rustc_target::callconv::FnAbi;
|
use rustc_target::callconv::FnAbi;
|
||||||
use tracing::{info, instrument, trace};
|
use tracing::{info, instrument, trace};
|
||||||
|
|
||||||
|
@ -80,7 +81,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||||
use rustc_middle::mir::StatementKind::*;
|
use rustc_middle::mir::StatementKind::*;
|
||||||
|
|
||||||
match &stmt.kind {
|
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 } => {
|
SetDiscriminant { place, variant_index } => {
|
||||||
let dest = self.eval_place(**place)?;
|
let dest = self.eval_place(**place)?;
|
||||||
|
@ -159,6 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||||
&mut self,
|
&mut self,
|
||||||
rvalue: &mir::Rvalue<'tcx>,
|
rvalue: &mir::Rvalue<'tcx>,
|
||||||
place: mir::Place<'tcx>,
|
place: mir::Place<'tcx>,
|
||||||
|
span: Span,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let dest = self.eval_place(place)?;
|
let dest = self.eval_place(place)?;
|
||||||
// FIXME: ensure some kind of non-aliasing between LHS and RHS?
|
// 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 src = self.eval_place(place)?;
|
||||||
let place = self.force_allocation(&src)?;
|
let place = self.force_allocation(&src)?;
|
||||||
let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
|
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.
|
// 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)?;
|
val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
|
||||||
}
|
}
|
||||||
self.write_immediate(*val, &dest)?;
|
self.write_immediate(*val, &dest)?;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use rustc_middle::mir::*;
|
||||||
use rustc_middle::thir::*;
|
use rustc_middle::thir::*;
|
||||||
use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
|
use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::Span;
|
use rustc_span::{DesugaringKind, Span};
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
|
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.
|
// the MIR we're building here needs to pass NLL later.
|
||||||
Operand::Copy(Place::from(place.local))
|
Operand::Copy(Place::from(place.local))
|
||||||
} else {
|
} 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 ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
|
||||||
let slice_ptr = self.temp(ptr_ty, span);
|
let slice_ptr = self.temp(ptr_ty, span);
|
||||||
self.cfg.push_assign(
|
self.cfg.push_assign(
|
||||||
block,
|
block,
|
||||||
source_info,
|
SourceInfo { span: len_span, ..source_info },
|
||||||
slice_ptr,
|
slice_ptr,
|
||||||
Rvalue::RawPtr(Mutability::Not, place),
|
Rvalue::RawPtr(Mutability::Not, place),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1163,6 +1163,9 @@ pub enum DesugaringKind {
|
||||||
WhileLoop,
|
WhileLoop,
|
||||||
/// `async Fn()` bound modifier
|
/// `async Fn()` bound modifier
|
||||||
BoundModifier,
|
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 {
|
impl DesugaringKind {
|
||||||
|
@ -1179,6 +1182,7 @@ impl DesugaringKind {
|
||||||
DesugaringKind::ForLoop => "`for` loop",
|
DesugaringKind::ForLoop => "`for` loop",
|
||||||
DesugaringKind::WhileLoop => "`while` loop",
|
DesugaringKind::WhileLoop => "`while` loop",
|
||||||
DesugaringKind::BoundModifier => "trait bound modifier",
|
DesugaringKind::BoundModifier => "trait bound modifier",
|
||||||
|
DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ fn main() {
|
||||||
let v1 = safe::as_mut_slice(&v);
|
let v1 = safe::as_mut_slice(&v);
|
||||||
let v2 = safe::as_mut_slice(&v);
|
let v2 = safe::as_mut_slice(&v);
|
||||||
v1[1] = 5;
|
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;
|
v2[1] = 7;
|
||||||
//~[tree]^ ERROR: /write access through .* is forbidden/
|
//~[tree]^ ERROR: /write access through .* is forbidden/
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error: Undefined Behavior: trying to retag from <TAG> 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 <TAG> 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
|
--> tests/fail/both_borrows/buggy_as_mut_slice.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | v1[1] = 5;
|
LL | v1[1] = 5;
|
||||||
| ^^^^^
|
| ^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| trying to retag from <TAG> for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
|
| attempting a write access using <TAG> at ALLOC[0x4], but that tag does not exist in the borrow stack for this location
|
||||||
| this error occurs as part of retag at ALLOC[0x0..0xc]
|
| 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: 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
|
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue