Skip to content

Commit 37d76c6

Browse files
committed
make retagging work even with 'unstable' places
1 parent a34a0c9 commit 37d76c6

File tree

3 files changed

+72
-32
lines changed

3 files changed

+72
-32
lines changed

src/borrow_tracker/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_target::abi::Size;
1111

1212
use crate::*;
1313
pub mod stacked_borrows;
14-
use stacked_borrows::diagnostics::RetagCause;
1514

1615
pub type CallId = NonZeroU64;
1716

@@ -265,11 +264,19 @@ impl GlobalStateInner {
265264

266265
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
267266
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
268-
fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
267+
fn retag_ptr_value(&mut self, kind: RetagKind, val: &ImmTy<'tcx, Provenance>) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
269268
let this = self.eval_context_mut();
270269
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
271270
match method {
272-
BorrowTrackerMethod::StackedBorrows => this.sb_retag(kind, place),
271+
BorrowTrackerMethod::StackedBorrows => this.sb_retag_ptr_value(kind, val),
272+
}
273+
}
274+
275+
fn retag_place_contents(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
276+
let this = self.eval_context_mut();
277+
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
278+
match method {
279+
BorrowTrackerMethod::StackedBorrows => this.sb_retag_place_contents(kind, place),
273280
}
274281
}
275282

src/borrow_tracker/stacked_borrows/mod.rs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
//! Implements "Stacked Borrows". See <https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md>
22
//! for further information.
33
4+
mod item;
5+
mod stack;
6+
pub mod diagnostics;
7+
48
use log::trace;
59
use std::cmp;
610
use std::fmt::{self, Write};
@@ -15,15 +19,13 @@ use rustc_target::abi::{Abi, Size};
1519

1620
use crate::borrow_tracker::{
1721
stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder, TagHistory},
18-
AccessKind, GlobalStateInner, ProtectorKind, RetagCause, RetagFields,
22+
AccessKind, GlobalStateInner, ProtectorKind, RetagFields,
1923
};
2024
use crate::*;
2125

22-
mod item;
2326
pub use item::{Item, Permission};
24-
mod stack;
2527
pub use stack::Stack;
26-
pub mod diagnostics;
28+
use diagnostics::RetagCause;
2729

2830
pub type AllocState = Stacks;
2931

@@ -807,17 +809,44 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
807809

808810
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
809811
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
810-
fn sb_retag(
812+
fn sb_retag_ptr_value(
813+
&mut self,
814+
kind: RetagKind,
815+
val: &ImmTy<'tcx, Provenance>,
816+
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
817+
let this = self.eval_context_mut();
818+
let ref_kind = match val.layout.ty.kind() {
819+
ty::Ref(_, _, mutbl) => {
820+
match mutbl {
821+
Mutability::Mut =>
822+
RefKind::Unique { two_phase: kind == RetagKind::TwoPhase },
823+
Mutability::Not => RefKind::Shared,
824+
}
825+
}
826+
ty::RawPtr(tym) => {
827+
RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }
828+
}
829+
_ => unreachable!(),
830+
};
831+
let retag_cause = match kind {
832+
RetagKind::TwoPhase { .. } => RetagCause::TwoPhase,
833+
RetagKind::FnEntry => unreachable!(),
834+
RetagKind::Raw | RetagKind::Default => RetagCause::Normal,
835+
};
836+
this.sb_retag_reference(&val, ref_kind, retag_cause, None)
837+
}
838+
839+
fn sb_retag_place_contents(
811840
&mut self,
812841
kind: RetagKind,
813842
place: &PlaceTy<'tcx, Provenance>,
814843
) -> InterpResult<'tcx> {
815844
let this = self.eval_context_mut();
816845
let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields;
817846
let retag_cause = match kind {
818-
RetagKind::TwoPhase { .. } => RetagCause::TwoPhase,
847+
RetagKind::Raw | RetagKind::TwoPhase { .. } => unreachable!(),
819848
RetagKind::FnEntry => RetagCause::FnEntry,
820-
RetagKind::Raw | RetagKind::Default => RetagCause::Normal,
849+
RetagKind::Default => RetagCause::Normal,
821850
};
822851
let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields };
823852
return visitor.visit_value(place);
@@ -831,7 +860,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
831860
}
832861
impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> {
833862
#[inline(always)] // yes this helps in our benchmarks
834-
fn retag_place(
863+
fn retag_ptr_inplace(
835864
&mut self,
836865
place: &PlaceTy<'tcx, Provenance>,
837866
ref_kind: RefKind,
@@ -856,7 +885,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
856885

857886
fn visit_box(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
858887
// Boxes get a weak protectors, since they may be deallocated.
859-
self.retag_place(
888+
self.retag_ptr_inplace(
860889
place,
861890
RefKind::Box,
862891
self.retag_cause,
@@ -879,10 +908,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
879908
ty::Ref(_, _, mutbl) => {
880909
let ref_kind = match mutbl {
881910
Mutability::Mut =>
882-
RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase },
911+
RefKind::Unique { two_phase: false },
883912
Mutability::Not => RefKind::Shared,
884913
};
885-
self.retag_place(
914+
self.retag_ptr_inplace(
886915
place,
887916
ref_kind,
888917
self.retag_cause,
@@ -891,21 +920,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
891920
.then_some(ProtectorKind::StrongProtector),
892921
)?;
893922
}
894-
ty::RawPtr(tym) => {
895-
// We definitely do *not* want to recurse into raw pointers -- wide raw
896-
// pointers have fields, and for dyn Trait pointees those can have reference
897-
// type!
898-
if self.kind == RetagKind::Raw {
899-
// Raw pointers need to be enabled.
900-
self.retag_place(
901-
place,
902-
RefKind::Raw { mutable: tym.mutbl == Mutability::Mut },
903-
self.retag_cause,
904-
/*protector*/ None,
905-
)?;
906-
}
923+
ty::RawPtr(..) => {
924+
// We do *not* want to recurse into raw pointers -- wide raw pointers have
925+
// fields, and for dyn Trait pointees those can have reference type!
907926
}
908-
_ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => {
927+
ty::Adt(adt, _) if adt.is_box() => {
909928
// Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
910929
// (Yes this means we technically also recursively retag the allocator itself
911930
// even if field retagging is not enabled. *shrug*)

src/machine.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -967,8 +967,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
967967
ptr: Pointer<Self::Provenance>,
968968
) -> InterpResult<'tcx> {
969969
match ptr.provenance {
970-
Provenance::Concrete { alloc_id, tag } =>
971-
intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag),
970+
Provenance::Concrete { alloc_id, tag } => {
971+
intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag)
972+
}
972973
Provenance::Wildcard => {
973974
// No need to do anything for wildcard pointers as
974975
// their provenances have already been previously exposed.
@@ -1055,13 +1056,26 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
10551056
}
10561057

10571058
#[inline(always)]
1058-
fn retag(
1059+
fn retag_ptr_value(
1060+
ecx: &mut InterpCx<'mir, 'tcx, Self>,
1061+
kind: mir::RetagKind,
1062+
val: &ImmTy<'tcx, Provenance>,
1063+
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
1064+
if ecx.machine.borrow_tracker.is_some() {
1065+
ecx.retag_ptr_value(kind, val)
1066+
} else {
1067+
Ok(val.clone())
1068+
}
1069+
}
1070+
1071+
#[inline(always)]
1072+
fn retag_place_contents(
10591073
ecx: &mut InterpCx<'mir, 'tcx, Self>,
10601074
kind: mir::RetagKind,
10611075
place: &PlaceTy<'tcx, Provenance>,
10621076
) -> InterpResult<'tcx> {
10631077
if ecx.machine.borrow_tracker.is_some() {
1064-
ecx.retag(kind, place)?;
1078+
ecx.retag_place_contents(kind, place)?;
10651079
}
10661080
Ok(())
10671081
}

0 commit comments

Comments
 (0)