Skip to content

Rollup of 3 pull requests #124060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
@@ -288,28 +288,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
}

/// Return the `AllocId` for the given thread-local static in the current thread.
fn thread_local_static_base_pointer(
fn thread_local_static_pointer(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Self::Provenance>> {
throw_unsup!(ThreadLocalStatic(def_id))
}

/// Return the root pointer for the given `extern static`.
fn extern_static_base_pointer(
/// Return the `AllocId` for the given `extern static`.
fn extern_static_pointer(
ecx: &InterpCx<'mir, 'tcx, Self>,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;

/// Return a "base" pointer for the given allocation: the one that is used for direct
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
///
/// Not called on `extern` or thread-local statics (those use the methods above).
fn adjust_alloc_base_pointer(
ecx: &InterpCx<'mir, 'tcx, Self>,
ptr: Pointer,
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;

/// "Int-to-pointer cast"
fn ptr_from_addr_cast(
ecx: &InterpCx<'mir, 'tcx, Self>,
@@ -336,6 +327,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {

/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
///
/// If `alloc` contains pointers, then they are all pointing to globals.
///
/// The way we construct allocations is to always first construct it without extra and then add
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
/// globals, and allocations created by Miri during evaluation.
@@ -354,6 +347,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;

/// Return a "root" pointer for the given allocation: the one that is used for direct
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
///
/// Not called on `extern` or thread-local statics (those use the methods above).
///
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when
/// it's a global and `GLOBAL_KIND` is `None`.
fn adjust_alloc_root_pointer(
ecx: &InterpCx<'mir, 'tcx, Self>,
ptr: Pointer,
kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;

/// Evaluate the inline assembly.
///
/// This should take care of jumping to the next block (one of `targets`) when asm goto
@@ -592,7 +598,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
Ok(alloc)
}

fn extern_static_base_pointer(
fn extern_static_pointer(
ecx: &InterpCx<$mir, $tcx, Self>,
def_id: DefId,
) -> InterpResult<$tcx, Pointer> {
@@ -601,9 +607,10 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
}

#[inline(always)]
fn adjust_alloc_base_pointer(
fn adjust_alloc_root_pointer(
_ecx: &InterpCx<$mir, $tcx, Self>,
ptr: Pointer<CtfeProvenance>,
_kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
Ok(ptr)
}
18 changes: 12 additions & 6 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
///
/// This function can fail only if `ptr` points to an `extern static`.
#[inline]
pub fn global_base_pointer(
pub fn global_root_pointer(
&self,
ptr: Pointer<CtfeProvenance>,
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
@@ -178,12 +178,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
bug!("global memory cannot point to thread-local static")
}
Some(GlobalAlloc::Static(def_id)) if self.tcx.is_foreign_item(def_id) => {
return M::extern_static_base_pointer(self, def_id);
return M::extern_static_pointer(self, def_id);
}
None => {
assert!(
self.memory.extra_fn_ptr_map.contains_key(&alloc_id),
"{alloc_id:?} is neither global nor a function pointer"
);
}
_ => {}
}
// And we need to get the provenance.
M::adjust_alloc_base_pointer(self, ptr)
M::adjust_alloc_root_pointer(self, ptr, M::GLOBAL_KIND.map(MemoryKind::Machine))
}

pub fn fn_ptr(&mut self, fn_val: FnVal<'tcx, M::ExtraFnVal>) -> Pointer<M::Provenance> {
@@ -197,9 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
id
}
};
// Functions are global allocations, so make sure we get the right base pointer.
// Functions are global allocations, so make sure we get the right root pointer.
// We know this is not an `extern static` so this cannot fail.
self.global_base_pointer(Pointer::from(id)).unwrap()
self.global_root_pointer(Pointer::from(id)).unwrap()
}

pub fn allocate_ptr(
@@ -240,7 +246,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
);
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
M::adjust_alloc_base_pointer(self, Pointer::from(id))
M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
}

pub fn reallocate_ptr(
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
@@ -764,15 +764,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Other cases need layout.
let adjust_scalar = |scalar| -> InterpResult<'tcx, _> {
Ok(match scalar {
Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size),
Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_root_pointer(ptr)?, size),
Scalar::Int(int) => Scalar::Int(int),
})
};
let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?;
let imm = match val_val {
mir::ConstValue::Indirect { alloc_id, offset } => {
// This is const data, no mutation allowed.
let ptr = self.global_base_pointer(Pointer::new(
let ptr = self.global_root_pointer(Pointer::new(
CtfeProvenance::from(alloc_id).as_immutable(),
offset,
))?;
@@ -784,7 +784,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// This is const data, no mutation allowed.
let alloc_id = self.tcx.reserve_and_set_memory_alloc(data);
let ptr = Pointer::new(CtfeProvenance::from(alloc_id).as_immutable(), Size::ZERO);
Immediate::new_slice(self.global_base_pointer(ptr)?.into(), meta, self)
Immediate::new_slice(self.global_root_pointer(ptr)?.into(), meta, self)
}
};
Ok(OpTy { op: Operand::Immediate(imm), layout })
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
@@ -1010,7 +1010,7 @@ where
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
// This must be an allocation in `tcx`
let _ = self.tcx.global_alloc(raw.alloc_id);
let ptr = self.global_base_pointer(Pointer::from(raw.alloc_id))?;
let ptr = self.global_root_pointer(Pointer::from(raw.alloc_id))?;
let layout = self.layout_of(raw.ty)?;
Ok(self.ptr_to_mplace(ptr.into(), layout))
}
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
@@ -144,7 +144,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
use rustc_middle::mir::Rvalue::*;
match *rvalue {
ThreadLocalRef(did) => {
let ptr = M::thread_local_static_base_pointer(self, did)?;
let ptr = M::thread_local_static_pointer(self, did)?;
self.write_pointer(ptr, &dest)?;
}

2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/traits.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;

let vtable_symbolic_allocation = self.tcx.reserve_and_set_vtable_alloc(ty, poly_trait_ref);
let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_symbolic_allocation))?;
let vtable_ptr = self.global_root_pointer(Pointer::from(vtable_symbolic_allocation))?;
Ok(vtable_ptr.into())
}

6 changes: 3 additions & 3 deletions library/std/src/io/cursor.rs
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ impl<T> Cursor<T> {
/// # force_inference(&buff);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(inner: T) -> Cursor<T> {
Cursor { pos: 0, inner }
}
@@ -132,7 +132,7 @@ impl<T> Cursor<T> {
/// let reference = buff.get_ref();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
pub const fn get_ref(&self) -> &T {
&self.inner
}
@@ -178,7 +178,7 @@ impl<T> Cursor<T> {
/// assert_eq!(buff.position(), 1);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
pub const fn position(&self) -> u64 {
self.pos
}
6 changes: 3 additions & 3 deletions library/std/src/io/util.rs
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ pub struct Empty;
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
pub const fn empty() -> Empty {
Empty
}
@@ -173,7 +173,7 @@ pub struct Repeat {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
pub const fn repeat(byte: u8) -> Repeat {
Repeat { byte }
}
@@ -276,7 +276,7 @@ pub struct Sink;
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
pub const fn sink() -> Sink {
Sink
}
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -407,7 +407,6 @@
// tidy-alphabetical-start
#![feature(const_collections_with_hasher)]
#![feature(const_hash)]
#![feature(const_io_structs)]
#![feature(const_ip)]
#![feature(const_ipv4)]
#![feature(const_ipv6)]
15 changes: 10 additions & 5 deletions src/tools/miri/src/alloc_addresses/mod.rs
Original file line number Diff line number Diff line change
@@ -141,7 +141,11 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}

fn addr_from_alloc_id(&self, alloc_id: AllocId) -> InterpResult<'tcx, u64> {
fn addr_from_alloc_id(
&self,
alloc_id: AllocId,
_kind: MemoryKind,
) -> InterpResult<'tcx, u64> {
let ecx = self.eval_context_ref();
let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
let global_state = &mut *global_state;
@@ -283,16 +287,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}

/// Convert a relative (tcx) pointer to a Miri pointer.
fn ptr_from_rel_ptr(
fn adjust_alloc_root_pointer(
&self,
ptr: Pointer<CtfeProvenance>,
tag: BorTag,
kind: MemoryKind,
) -> InterpResult<'tcx, Pointer<Provenance>> {
let ecx = self.eval_context_ref();

let (prov, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
let alloc_id = prov.alloc_id();
let base_addr = ecx.addr_from_alloc_id(alloc_id)?;
let base_addr = ecx.addr_from_alloc_id(alloc_id, kind)?;

// Add offset with the right kind of pointer-overflowing arithmetic.
let dl = ecx.data_layout();
@@ -314,9 +319,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
ecx.alloc_id_from_addr(addr.bytes())?
};

// This cannot fail: since we already have a pointer with that provenance, rel_ptr_to_addr
// This cannot fail: since we already have a pointer with that provenance, adjust_alloc_root_pointer
// must have been called in the past, so we can just look up the address in the map.
let base_addr = ecx.addr_from_alloc_id(alloc_id).unwrap();
let base_addr = *ecx.machine.alloc_addresses.borrow().base_addr.get(&alloc_id).unwrap();

// Wrapping "addr - base_addr"
#[allow(clippy::cast_possible_wrap)] // we want to wrap here
18 changes: 9 additions & 9 deletions src/tools/miri/src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
@@ -89,10 +89,10 @@ pub struct GlobalStateInner {
borrow_tracker_method: BorrowTrackerMethod,
/// Next unused pointer ID (tag).
next_ptr_tag: BorTag,
/// Table storing the "base" tag for each allocation.
/// The base tag is the one used for the initial pointer.
/// Table storing the "root" tag for each allocation.
/// The root tag is the one used for the initial pointer.
/// We need this in a separate table to handle cyclic statics.
base_ptr_tags: FxHashMap<AllocId, BorTag>,
root_ptr_tags: FxHashMap<AllocId, BorTag>,
/// Next unused call ID (for protectors).
next_call_id: CallId,
/// All currently protected tags.
@@ -175,7 +175,7 @@ impl GlobalStateInner {
GlobalStateInner {
borrow_tracker_method,
next_ptr_tag: BorTag::one(),
base_ptr_tags: FxHashMap::default(),
root_ptr_tags: FxHashMap::default(),
next_call_id: NonZero::new(1).unwrap(),
protected_tags: FxHashMap::default(),
tracked_pointer_tags,
@@ -213,8 +213,8 @@ impl GlobalStateInner {
}
}

pub fn base_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag {
self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| {
pub fn root_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag {
self.root_ptr_tags.get(&id).copied().unwrap_or_else(|| {
let tag = self.new_ptr();
if self.tracked_pointer_tags.contains(&tag) {
machine.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
@@ -223,14 +223,14 @@ impl GlobalStateInner {
None,
));
}
trace!("New allocation {:?} has base tag {:?}", id, tag);
self.base_ptr_tags.try_insert(id, tag).unwrap();
trace!("New allocation {:?} has rpot tag {:?}", id, tag);
self.root_ptr_tags.try_insert(id, tag).unwrap();
tag
})
}

pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_, '_>) {
self.base_ptr_tags.retain(|id, _| allocs.is_live(*id));
self.root_ptr_tags.retain(|id, _| allocs.is_live(*id));
}
}

12 changes: 6 additions & 6 deletions src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ fn err_sb_ub<'tcx>(
#[derive(Clone, Debug)]
pub struct AllocHistory {
id: AllocId,
base: (Item, Span),
root: (Item, Span),
creations: smallvec::SmallVec<[Creation; 1]>,
invalidations: smallvec::SmallVec<[Invalidation; 1]>,
protectors: smallvec::SmallVec<[Protection; 1]>,
@@ -225,7 +225,7 @@ impl AllocHistory {
pub fn new(id: AllocId, item: Item, machine: &MiriMachine<'_, '_>) -> Self {
Self {
id,
base: (item, machine.current_span()),
root: (item, machine.current_span()),
creations: SmallVec::new(),
invalidations: SmallVec::new(),
protectors: SmallVec::new(),
@@ -342,15 +342,15 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
})
})
.or_else(|| {
// If we didn't find a retag that created this tag, it might be the base tag of
// If we didn't find a retag that created this tag, it might be the root tag of
// this allocation.
if self.history.base.0.tag() == tag {
if self.history.root.0.tag() == tag {
Some((
format!(
"{tag:?} was created here, as the base tag for {:?}",
"{tag:?} was created here, as the root tag for {:?}",
self.history.id
),
self.history.base.1.data(),
self.history.root.1.data(),
))
} else {
None
4 changes: 2 additions & 2 deletions src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
@@ -518,9 +518,9 @@ impl Stacks {
// not through a pointer). That is, whenever we directly write to a local, this will pop
// everything else off the stack, invalidating all previous pointers,
// and in particular, *all* raw pointers.
MemoryKind::Stack => (state.base_ptr_tag(id, machine), Permission::Unique),
MemoryKind::Stack => (state.root_ptr_tag(id, machine), Permission::Unique),
// Everything else is shared by default.
_ => (state.base_ptr_tag(id, machine), Permission::SharedReadWrite),
_ => (state.root_ptr_tag(id, machine), Permission::SharedReadWrite),
};
Stacks::new(size, perm, base_tag, id, machine)
}
10 changes: 5 additions & 5 deletions src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ impl Stack {
let mut first_removed = None;

// We never consider removing the bottom-most tag. For stacks without an unknown
// bottom this preserves the base tag.
// bottom this preserves the root tag.
// Note that the algorithm below is based on considering the tag at read_idx - 1,
// so precisely considering the tag at index 0 for removal when we have an unknown
// bottom would complicate the implementation. The simplification of not considering
@@ -93,7 +93,7 @@ impl Stack {
self.unique_range = 0..self.len();
}

// Replace any Items which have been collected with the base item, a known-good value.
// Replace any Items which have been collected with the root item, a known-good value.
for i in 0..CACHE_LEN {
if self.cache.idx[i] >= first_removed {
self.cache.items[i] = self.borrows[0];
@@ -331,7 +331,7 @@ impl<'tcx> Stack {
self.verify_cache_consistency();
}

/// Construct a new `Stack` using the passed `Item` as the base tag.
/// Construct a new `Stack` using the passed `Item` as the root tag.
pub fn new(item: Item) -> Self {
Stack {
borrows: vec![item],
@@ -438,8 +438,8 @@ impl<'tcx> Stack {
let mut removed = 0;
let mut cursor = 0;
// Remove invalid entries from the cache by rotating them to the end of the cache, then
// keep track of how many invalid elements there are and overwrite them with the base tag.
// The base tag here serves as a harmless default value.
// keep track of how many invalid elements there are and overwrite them with the root tag.
// The root tag here serves as a harmless default value.
for _ in 0..CACHE_LEN - 1 {
if self.cache.idx[cursor] >= start {
self.cache.idx[cursor..CACHE_LEN - removed].rotate_left(1);
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ impl<'tcx> Tree {
_kind: MemoryKind,
machine: &MiriMachine<'_, 'tcx>,
) -> Self {
let tag = state.base_ptr_tag(id, machine); // Fresh tag for the root
let tag = state.root_ptr_tag(id, machine); // Fresh tag for the root
let span = machine.current_span();
Tree::new(tag, size, span)
}
22 changes: 12 additions & 10 deletions src/tools/miri/src/machine.rs
Original file line number Diff line number Diff line change
@@ -503,7 +503,7 @@ pub struct MiriMachine<'mir, 'tcx> {
/// Crates which are considered local for the purposes of error reporting.
pub(crate) local_crates: Vec<CrateNum>,

/// Mapping extern static names to their base pointer.
/// Mapping extern static names to their pointer.
extern_statics: FxHashMap<Symbol, Pointer<Provenance>>,

/// The random number generator used for resolving non-determinism.
@@ -1042,14 +1042,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
ecx.generate_nan(inputs)
}

fn thread_local_static_base_pointer(
fn thread_local_static_pointer(
ecx: &mut MiriInterpCx<'mir, 'tcx>,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Provenance>> {
ecx.get_or_create_thread_local_alloc(def_id)
}

fn extern_static_base_pointer(
fn extern_static_pointer(
ecx: &MiriInterpCx<'mir, 'tcx>,
def_id: DefId,
) -> InterpResult<'tcx, Pointer<Provenance>> {
@@ -1090,7 +1090,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
alloc: Cow<'b, Allocation>,
kind: Option<MemoryKind>,
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> {
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
if ecx.machine.tracked_alloc_ids.contains(&id) {
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
id,
@@ -1135,7 +1135,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
weak_memory: buffer_alloc,
backtrace,
},
|ptr| ecx.global_base_pointer(ptr),
|ptr| ecx.global_root_pointer(ptr),
)?;

if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
@@ -1148,31 +1148,33 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
Ok(Cow::Owned(alloc))
}

fn adjust_alloc_base_pointer(
fn adjust_alloc_root_pointer(
ecx: &MiriInterpCx<'mir, 'tcx>,
ptr: Pointer<CtfeProvenance>,
kind: Option<MemoryKind>,
) -> InterpResult<'tcx, Pointer<Provenance>> {
let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
let alloc_id = ptr.provenance.alloc_id();
if cfg!(debug_assertions) {
// The machine promises to never call us on thread-local or extern statics.
match ecx.tcx.try_get_global_alloc(alloc_id) {
Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_thread_local_static(def_id) => {
panic!("adjust_alloc_base_pointer called on thread-local static")
panic!("adjust_alloc_root_pointer called on thread-local static")
}
Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_foreign_item(def_id) => {
panic!("adjust_alloc_base_pointer called on extern static")
panic!("adjust_alloc_root_pointer called on extern static")
}
_ => {}
}
}
// FIXME: can we somehow preserve the immutability of `ptr`?
let tag = if let Some(borrow_tracker) = &ecx.machine.borrow_tracker {
borrow_tracker.borrow_mut().base_ptr_tag(alloc_id, &ecx.machine)
borrow_tracker.borrow_mut().root_ptr_tag(alloc_id, &ecx.machine)
} else {
// Value does not matter, SB is disabled
BorTag::default()
};
ecx.ptr_from_rel_ptr(ptr, tag)
ecx.adjust_alloc_root_pointer(ptr, tag, kind)
}

/// Called on `usize as ptr` casts.
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ LL | unsafe { *x = 0 };
|
= 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: <TAG> was created here, as the base tag for ALLOC
help: <TAG> was created here, as the root tag for ALLOC
--> $DIR/invalidate_against_protector3.rs:LL:CC
|
LL | let ptr = alloc(Layout::for_value(&0i32)) as *mut i32;