Skip to content

Commit

Permalink
strict provenance: rename addr → addr_without_provenance
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Feb 25, 2024
1 parent e9f9594 commit 9bf5abe
Show file tree
Hide file tree
Showing 41 changed files with 181 additions and 141 deletions.
18 changes: 10 additions & 8 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ impl<T> TypedArena<T> {
fn can_allocate(&self, additional: usize) -> bool {
// FIXME: this should *likely* use `offset_from`, but more
// investigation is needed (including running tests in miri).
let available_bytes = self.end.get().addr() - self.ptr.get().addr();
let available_bytes =
self.end.get().addr_without_provenance() - self.ptr.get().addr_without_provenance();
let additional_bytes = additional.checked_mul(mem::size_of::<T>()).unwrap();
available_bytes >= additional_bytes
}
Expand Down Expand Up @@ -245,7 +246,8 @@ impl<T> TypedArena<T> {
if mem::needs_drop::<T>() {
// FIXME: this should *likely* use `offset_from`, but more
// investigation is needed (including running tests in miri).
let used_bytes = self.ptr.get().addr() - last_chunk.start().addr();
let used_bytes = self.ptr.get().addr_without_provenance()
- last_chunk.start().addr_without_provenance();
last_chunk.entries = used_bytes / mem::size_of::<T>();
}

Expand All @@ -271,9 +273,9 @@ impl<T> TypedArena<T> {
// chunks.
fn clear_last_chunk(&self, last_chunk: &mut ArenaChunk<T>) {
// Determine how much was filled.
let start = last_chunk.start().addr();
let start = last_chunk.start().addr_without_provenance();
// We obtain the value of the pointer to the first uninitialized element.
let end = self.ptr.get().addr();
let end = self.ptr.get().addr_without_provenance();
// We then calculate the number of elements to be dropped in the last chunk,
// which is the filled area's length.
let diff = if mem::size_of::<T>() == 0 {
Expand Down Expand Up @@ -396,11 +398,11 @@ impl DroplessArena {
self.start.set(chunk.start());

// Align the end to DROPLESS_ALIGNMENT.
let end = align_down(chunk.end().addr(), DROPLESS_ALIGNMENT);
let end = align_down(chunk.end().addr_without_provenance(), DROPLESS_ALIGNMENT);

// Make sure we don't go past `start`. This should not happen since the allocation
// should be at least DROPLESS_ALIGNMENT - 1 bytes.
debug_assert!(chunk.start().addr() <= end);
debug_assert!(chunk.start().addr_without_provenance() <= end);

self.end.set(chunk.end().with_addr(end));

Expand All @@ -415,9 +417,9 @@ impl DroplessArena {
// This loop executes once or twice: if allocation fails the first
// time, the `grow` ensures it will succeed the second time.
loop {
let start = self.start.get().addr();
let start = self.start.get().addr_without_provenance();
let old_end = self.end.get();
let end = old_end.addr();
let end = old_end.addr_without_provenance();

// Align allocated bytes so that `self.end` stays aligned to
// DROPLESS_ALIGNMENT.
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_ssa/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
fn to_raw_string(&self) -> String {
match *self {
MonoItem::Fn(instance) => {
format!("Fn({:?}, {})", instance.def, instance.args.as_ptr().addr())
format!(
"Fn({:?}, {})",
instance.def,
instance.args.as_ptr().addr_without_provenance()
)
}
MonoItem::Static(id) => format!("Static({id:?})"),
MonoItem::GlobalAsm(id) => format!("GlobalAsm({id:?})"),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/tagged_ptr/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ where
#[inline]
pub fn tag(&self) -> T {
// Unpack the tag, according to the `self.packed` encoding scheme
let tag = self.packed.addr().get() >> Self::TAG_BIT_SHIFT;
let tag = self.packed.addr_without_provenance().get() >> Self::TAG_BIT_SHIFT;

// Safety:
// The shift retrieves the original value from `T::into_usize`,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/generic_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl<'tcx> GenericArg<'tcx> {
// pointers were originally created from `Interned` types in `pack()`,
// and this is just going in the other direction.
unsafe {
match self.ptr.addr().get() & TAG_MASK {
match self.ptr.addr_without_provenance().get() & TAG_MASK {
REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
ptr.cast::<ty::RegionKind<'tcx>>().as_ref(),
))),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ impl<'tcx> Term<'tcx> {
// pointers were originally created from `Interned` types in `pack()`,
// and this is just going in the other direction.
unsafe {
match self.ptr.addr().get() & TAG_MASK {
match self.ptr.addr_without_provenance().get() & TAG_MASK {
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
))),
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2840,7 +2840,7 @@ impl<T, A: Allocator> Weak<T, A> {
}

pub(crate) fn is_dangling<T: ?Sized>(ptr: *const T) -> bool {
(ptr.cast::<()>()).addr() == usize::MAX
(ptr.cast::<()>()).addr_without_provenance() == usize::MAX
}

/// Helper type to allow accessing the reference counts without
Expand Down
4 changes: 3 additions & 1 deletion library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,9 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let exact = if T::IS_ZST {
self.end.addr().wrapping_sub(self.ptr.as_ptr().addr())
self.end
.addr_without_provenance()
.wrapping_sub(self.ptr.as_ptr().addr_without_provenance())
} else {
unsafe { non_null!(self.end, T).sub_ptr(self.ptr) }
};
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ mod impls {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
let (address, metadata) = self.to_raw_parts();
state.write_usize(address.addr());
state.write_usize(address.addr_without_provenance());
metadata.hash(state);
}
}
Expand All @@ -965,7 +965,7 @@ mod impls {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
let (address, metadata) = self.to_raw_parts();
state.write_usize(address.addr());
state.write_usize(address.addr_without_provenance());
metadata.hash(state);
}
}
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,7 @@ extern "rust-intrinsic" {
/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
/// type for that buffer, it can use [`MaybeUninit`][crate::mem::MaybeUninit].
/// - If the code actually wants to work on the address the pointer points to, it can use `as`
/// casts or [`ptr.addr()`][pointer::addr].
/// casts or [`ptr.addr_without_provenance()`][pointer::addr_without_provenance].
///
/// Turning a `*mut T` into an `&mut T`:
///
Expand Down Expand Up @@ -2760,8 +2760,8 @@ pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool {
/// `count * size` do *not* overlap.
#[inline]
pub(crate) fn is_nonoverlapping(src: *const (), dst: *const (), size: usize, count: usize) -> bool {
let src_usize = src.addr();
let dst_usize = dst.addr();
let src_usize = src.addr_without_provenance();
let dst_usize = dst.addr_without_provenance();
let Some(size) = size.checked_mul(count) else {
crate::panicking::panic_nounwind(
"is_nonoverlapping: `size_of::<T>() * count` overflows a usize",
Expand Down
16 changes: 8 additions & 8 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<T: ?Sized> *const T {
pub const fn is_null(self) -> bool {
#[inline]
fn runtime_impl(ptr: *const u8) -> bool {
ptr.addr() == 0
ptr.addr_without_provenance() == 0
}

#[inline]
Expand Down Expand Up @@ -203,7 +203,7 @@ impl<T: ?Sized> *const T {
#[must_use]
#[inline(always)]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub fn addr(self) -> usize {
pub fn addr_without_provenance(self) -> usize {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
// provenance).
Expand All @@ -223,7 +223,7 @@ impl<T: ?Sized> *const T {
/// Provenance][super#strict-provenance] rules. Supporting
/// [`from_exposed_addr`][] complicates specification and reasoning and may not be supported by
/// tools that help you to stay conformant with the Rust memory model, so it is recommended to
/// use [`addr`][pointer::addr] wherever possible.
/// use [`addr_without_provenance`][pointer::addr_without_provenance] wherever possible.
///
/// On most platforms this will produce a value with the same bytes as the original pointer,
/// because all the bytes are dedicated to describing the address. Platforms which need to store
Expand Down Expand Up @@ -264,7 +264,7 @@ impl<T: ?Sized> *const T {
// In the mean-time, this operation is defined to be "as if" it was
// a wrapping_offset, so we can emulate it as such. This should properly
// restore pointer provenance even under today's compiler.
let self_addr = self.addr() as isize;
let self_addr = self.addr_without_provenance() as isize;
let dest_addr = addr as isize;
let offset = dest_addr.wrapping_sub(self_addr);

Expand All @@ -282,7 +282,7 @@ impl<T: ?Sized> *const T {
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {
self.with_addr(f(self.addr()))
self.with_addr(f(self.addr_without_provenance()))
}

/// Decompose a (possibly wide) pointer into its data pointer and metadata components.
Expand Down Expand Up @@ -592,7 +592,7 @@ impl<T: ?Sized> *const T {
/// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
///
/// // Get the "tag" back
/// let tag = tagged_ptr.addr() & tag_mask;
/// let tag = tagged_ptr.addr_without_provenance() & tag_mask;
/// assert_eq!(tag, 0b10);
///
/// // Note that `tagged_ptr` is unaligned, it's UB to read from it.
Expand Down Expand Up @@ -664,7 +664,7 @@ impl<T: ?Sized> *const T {
/// runtime and may be exploited by optimizations. If you wish to compute the difference between
/// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
/// origin as isize) / mem::size_of::<T>()`.
// FIXME: recommend `addr()` instead of `as usize` once that is stable.
// FIXME: recommend `addr_without_provenance()` instead of `as usize` once that is stable.
///
/// [`add`]: #method.add
/// [allocated object]: crate::ptr#allocated-object
Expand Down Expand Up @@ -1611,7 +1611,7 @@ impl<T: ?Sized> *const T {

#[inline]
fn runtime_impl(ptr: *const (), align: usize) -> bool {
ptr.addr() & (align - 1) == 0
ptr.addr_without_provenance() & (align - 1) == 0
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@
//! [`wrapping_offset`]: pointer::wrapping_offset
//! [`with_addr`]: pointer::with_addr
//! [`map_addr`]: pointer::map_addr
//! [`addr`]: pointer::addr
//! [`addr_without_provenance`]: pointer::addr_without_provenance
//! [`ptr::dangling`]: core::ptr::dangling
//! [`expose_addr`]: pointer::expose_addr
//! [`from_exposed_addr`]: from_exposed_addr
Expand Down
16 changes: 8 additions & 8 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<T: ?Sized> *mut T {
pub const fn is_null(self) -> bool {
#[inline]
fn runtime_impl(ptr: *mut u8) -> bool {
ptr.addr() == 0
ptr.addr_without_provenance() == 0
}

#[inline]
Expand Down Expand Up @@ -211,7 +211,7 @@ impl<T: ?Sized> *mut T {
#[must_use]
#[inline(always)]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub fn addr(self) -> usize {
pub fn addr_without_provenance(self) -> usize {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
// provenance).
Expand All @@ -231,7 +231,7 @@ impl<T: ?Sized> *mut T {
/// Provenance][super#strict-provenance] rules. Supporting
/// [`from_exposed_addr_mut`][] complicates specification and reasoning and may not be supported
/// by tools that help you to stay conformant with the Rust memory model, so it is recommended
/// to use [`addr`][pointer::addr] wherever possible.
/// to use [`addr_without_provenance`][pointer::addr_without_provenance] wherever possible.
///
/// On most platforms this will produce a value with the same bytes as the original pointer,
/// because all the bytes are dedicated to describing the address. Platforms which need to store
Expand Down Expand Up @@ -272,7 +272,7 @@ impl<T: ?Sized> *mut T {
// In the mean-time, this operation is defined to be "as if" it was
// a wrapping_offset, so we can emulate it as such. This should properly
// restore pointer provenance even under today's compiler.
let self_addr = self.addr() as isize;
let self_addr = self.addr_without_provenance() as isize;
let dest_addr = addr as isize;
let offset = dest_addr.wrapping_sub(self_addr);

Expand All @@ -290,7 +290,7 @@ impl<T: ?Sized> *mut T {
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {
self.with_addr(f(self.addr()))
self.with_addr(f(self.addr_without_provenance()))
}

/// Decompose a (possibly wide) pointer into its data pointer and metadata components.
Expand Down Expand Up @@ -607,7 +607,7 @@ impl<T: ?Sized> *mut T {
/// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
///
/// // Get the "tag" back
/// let tag = tagged_ptr.addr() & tag_mask;
/// let tag = tagged_ptr.addr_without_provenance() & tag_mask;
/// assert_eq!(tag, 0b10);
///
/// // Note that `tagged_ptr` is unaligned, it's UB to read from/write to it.
Expand Down Expand Up @@ -839,7 +839,7 @@ impl<T: ?Sized> *mut T {
/// runtime and may be exploited by optimizations. If you wish to compute the difference between
/// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
/// origin as isize) / mem::size_of::<T>()`.
// FIXME: recommend `addr()` instead of `as usize` once that is stable.
// FIXME: recommend `addr_without_provenance()` instead of `as usize` once that is stable.
///
/// [`add`]: #method.add
/// [allocated object]: crate::ptr#allocated-object
Expand Down Expand Up @@ -1884,7 +1884,7 @@ impl<T: ?Sized> *mut T {

#[inline]
fn runtime_impl(ptr: *mut (), align: usize) -> bool {
ptr.addr() & (align - 1) == 0
ptr.addr_without_provenance() & (align - 1) == 0
}

#[inline]
Expand Down
14 changes: 7 additions & 7 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,17 @@ impl<T: ?Sized> NonNull<T> {

/// Gets the "address" portion of the pointer.
///
/// For more details see the equivalent method on a raw pointer, [`pointer::addr`].
/// For more details see the equivalent method on a raw pointer, [`pointer::addr_without_provenance`].
///
/// This API and its claimed semantics are part of the Strict Provenance experiment,
/// see the [`ptr` module documentation][crate::ptr].
#[must_use]
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub fn addr(self) -> NonZero<usize> {
pub fn addr_without_provenance(self) -> NonZero<usize> {
// SAFETY: The pointer is guaranteed by the type to be non-null,
// meaning that the address will be non-zero.
unsafe { NonZero::new_unchecked(self.pointer.addr()) }
unsafe { NonZero::new_unchecked(self.pointer.addr_without_provenance()) }
}

/// Creates a new pointer with the given address.
Expand All @@ -321,7 +321,7 @@ impl<T: ?Sized> NonNull<T> {
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
pub fn map_addr(self, f: impl FnOnce(NonZero<usize>) -> NonZero<usize>) -> Self {
self.with_addr(f(self.addr()))
self.with_addr(f(self.addr_without_provenance()))
}

/// Acquires the underlying `*mut` pointer.
Expand Down Expand Up @@ -803,7 +803,7 @@ impl<T: ?Sized> NonNull<T> {
/// runtime and may be exploited by optimizations. If you wish to compute the difference between
/// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
/// origin as isize) / mem::size_of::<T>()`.
// FIXME: recommend `addr()` instead of `as usize` once that is stable.
// FIXME: recommend `addr_without_provenance()` instead of `as usize` once that is stable.
///
/// [`add`]: #method.add
/// [allocated object]: crate::ptr#allocated-object
Expand Down Expand Up @@ -839,10 +839,10 @@ impl<T: ?Sized> NonNull<T> {
///
/// let ptr1 = NonNull::new(Box::into_raw(Box::new(0u8))).unwrap();
/// let ptr2 = NonNull::new(Box::into_raw(Box::new(1u8))).unwrap();
/// let diff = (ptr2.addr().get() as isize).wrapping_sub(ptr1.addr().get() as isize);
/// let diff = (ptr2.addr_without_provenance().get() as isize).wrapping_sub(ptr1.addr_without_provenance().get() as isize);
/// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
/// let ptr2_other = NonNull::new(ptr1.as_ptr().wrapping_byte_offset(diff)).unwrap();
/// assert_eq!(ptr2.addr(), ptr2_other.addr());
/// assert_eq!(ptr2.addr_without_provenance(), ptr2_other.addr_without_provenance());
/// // Since ptr2_other and ptr2 are derived from pointers to different objects,
/// // computing their offset is undefined behavior, even though
/// // they point to the same address!
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/iter/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ macro_rules! if_zst {
#![allow(unused_unsafe)] // we're sometimes used within an unsafe block

if T::IS_ZST {
let $len = $this.end_or_len.addr();
let $len = $this.end_or_len.addr_without_provenance();
$zst_body
} else {
// SAFETY: for non-ZSTs, the type invariant ensures it cannot be null
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ where
assert!(mem::size_of::<T>() > 0);
// FIXME: this should *likely* use `offset_from`, but more
// investigation is needed (including running tests in miri).
(r.addr() - l.addr()) / mem::size_of::<T>()
(r.addr_without_provenance() - l.addr_without_provenance()) / mem::size_of::<T>()
}

loop {
Expand Down
Loading

0 comments on commit 9bf5abe

Please sign in to comment.