mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
miri tree borrows: skip retag_reference early if there is no NewPermission
This commit is contained in:
parent
dd453a6a99
commit
95392ef0c9
@ -178,7 +178,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>, // parent tag extracted from here
|
||||
ptr_size: Size,
|
||||
new_perm: Option<NewPermission>,
|
||||
new_perm: NewPermission,
|
||||
new_tag: BorTag,
|
||||
) -> InterpResult<'tcx, Option<(AllocId, BorTag)>> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -256,10 +256,6 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
||||
ptr_size.bytes()
|
||||
);
|
||||
|
||||
let Some(new_perm) = new_perm else {
|
||||
return Ok(Some((alloc_id, orig_tag)));
|
||||
};
|
||||
|
||||
if let Some(protect) = new_perm.protector {
|
||||
// We register the protection in two different places.
|
||||
// This makes creating a protector slower, but checking whether a tag
|
||||
@ -305,7 +301,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
||||
fn tb_retag_reference(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
new_perm: Option<NewPermission>,
|
||||
new_perm: NewPermission,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
// We want a place for where the ptr *points to*, so we get one.
|
||||
@ -317,7 +313,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
||||
// - if the pointer is not reborrowed (raw pointer) or if `zero_size` is set
|
||||
// then we override the size to do a zero-length reborrow.
|
||||
let reborrow_size = match new_perm {
|
||||
Some(NewPermission { zero_size: false, .. }) =>
|
||||
NewPermission { zero_size: false, .. } =>
|
||||
this.size_and_align_of_mplace(&place)?
|
||||
.map(|(size, _)| size)
|
||||
.unwrap_or(place.layout.size),
|
||||
@ -374,7 +370,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
NewPermission::from_ref_ty(pointee, mutability, kind, this),
|
||||
_ => None,
|
||||
};
|
||||
this.tb_retag_reference(val, new_perm)
|
||||
if let Some(new_perm) = new_perm {
|
||||
this.tb_retag_reference(val, new_perm)
|
||||
} else {
|
||||
Ok(val.clone())
|
||||
}
|
||||
}
|
||||
|
||||
/// Retag all pointers that are stored in this place.
|
||||
@ -405,9 +405,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
new_perm: Option<NewPermission>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
|
||||
let val = self.ecx.tb_retag_reference(&val, new_perm)?;
|
||||
self.ecx.write_immediate(*val, place)?;
|
||||
if let Some(new_perm) = new_perm {
|
||||
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
|
||||
let val = self.ecx.tb_retag_reference(&val, new_perm)?;
|
||||
self.ecx.write_immediate(*val, place)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -505,11 +507,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?;
|
||||
let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout);
|
||||
// Reborrow it. With protection! That is the entire point.
|
||||
let new_perm = Some(NewPermission {
|
||||
let new_perm = NewPermission {
|
||||
initial_state: Permission::new_active(),
|
||||
zero_size: false,
|
||||
protector: Some(ProtectorKind::StrongProtector),
|
||||
});
|
||||
};
|
||||
let _new_ptr = this.tb_retag_reference(&ptr, new_perm)?;
|
||||
// We just throw away `new_ptr`, so nobody can access this memory while it is protected.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user