1
Fork 0

rename ptr::from_exposed_addr -> ptr::with_exposed_provenance

This commit is contained in:
Ralf Jung 2024-03-23 11:47:11 +01:00
parent c3b05c6e5b
commit 67b9d7d184
31 changed files with 85 additions and 85 deletions

View file

@ -86,7 +86,7 @@ hir_typeck_invalid_callee = expected function, found {$ty}
hir_typeck_lossy_provenance_int2ptr = hir_typeck_lossy_provenance_int2ptr =
strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}` strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`
.suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address .suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
.help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead .help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
hir_typeck_lossy_provenance_ptr2int = hir_typeck_lossy_provenance_ptr2int =
under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}` under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`

View file

@ -2749,7 +2749,7 @@ declare_lint! {
/// memory the pointer is allowed to read/write. Casting an integer, which /// memory the pointer is allowed to read/write. Casting an integer, which
/// doesn't have provenance, to a pointer requires the compiler to assign /// doesn't have provenance, to a pointer requires the compiler to assign
/// (guess) provenance. The compiler assigns "all exposed valid" (see the /// (guess) provenance. The compiler assigns "all exposed valid" (see the
/// docs of [`ptr::from_exposed_addr`] for more information about this /// docs of [`ptr::with_exposed_provenance`] for more information about this
/// "exposing"). This penalizes the optimiser and is not well suited for /// "exposing"). This penalizes the optimiser and is not well suited for
/// dynamic analysis/dynamic program verification (e.g. Miri or CHERI /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
/// platforms). /// platforms).
@ -2757,11 +2757,11 @@ declare_lint! {
/// It is much better to use [`ptr::with_addr`] instead to specify the /// It is much better to use [`ptr::with_addr`] instead to specify the
/// provenance you want. If using this function is not possible because the /// provenance you want. If using this function is not possible because the
/// code relies on exposed provenance then there is as an escape hatch /// code relies on exposed provenance then there is as an escape hatch
/// [`ptr::from_exposed_addr`]. /// [`ptr::with_exposed_provenance`].
/// ///
/// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
/// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr
/// [`ptr::from_exposed_addr`]: https://doc.rust-lang.org/core/ptr/fn.from_exposed_addr.html /// [`ptr::with_exposed_provenance`]: https://doc.rust-lang.org/core/ptr/fn.with_exposed_provenance.html
pub FUZZY_PROVENANCE_CASTS, pub FUZZY_PROVENANCE_CASTS,
Allow, Allow,
"a fuzzy integer to pointer cast is used", "a fuzzy integer to pointer cast is used",

View file

@ -1318,7 +1318,7 @@ pub enum CastKind {
/// See the docs on `expose_addr` for more details. /// See the docs on `expose_addr` for more details.
PointerExposeAddress, PointerExposeAddress,
/// An address-to-pointer cast that picks up an exposed provenance. /// An address-to-pointer cast that picks up an exposed provenance.
/// See the docs on `from_exposed_addr` for more details. /// See the docs on `with_exposed_provenance` for more details.
PointerFromExposedAddress, PointerFromExposedAddress,
/// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are /// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
/// translated into `&raw mut/const *r`, i.e., they are not actually casts. /// translated into `&raw mut/const *r`, i.e., they are not actually casts.

View file

@ -165,7 +165,7 @@ impl<T: ?Sized> *const T {
#[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
#[deprecated( #[deprecated(
since = "1.67.0", since = "1.67.0",
note = "replaced by the `ptr::from_exposed_addr` function, or update \ note = "replaced by the `ptr::with_exposed_provenance` function, or update \
your code to follow the strict provenance rules using its APIs" your code to follow the strict provenance rules using its APIs"
)] )]
#[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function #[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function
@ -187,7 +187,7 @@ impl<T: ?Sized> *const T {
/// ///
/// If using those APIs is not possible because there is no way to preserve a pointer with the /// If using those APIs is not possible because there is no way to preserve a pointer with the
/// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
/// or [`expose_addr`][pointer::expose_addr] and [`from_exposed_addr`][from_exposed_addr] /// or [`expose_addr`][pointer::expose_addr] and [`with_exposed_provenance`][with_exposed_provenance]
/// instead. However, note that this makes your code less portable and less amenable to tools /// instead. However, note that this makes your code less portable and less amenable to tools
/// that check for compliance with the Rust memory model. /// that check for compliance with the Rust memory model.
/// ///
@ -211,30 +211,30 @@ impl<T: ?Sized> *const T {
} }
/// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
/// use in [`from_exposed_addr`][]. /// use in [`with_exposed_provenance`][].
/// ///
/// This is equivalent to `self as usize`, which semantically discards *provenance* and /// This is equivalent to `self as usize`, which semantically discards *provenance* and
/// *address-space* information. Furthermore, this (like the `as` cast) has the implicit /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
/// side-effect of marking the provenance as 'exposed', so on platforms that support it you can /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
/// later call [`from_exposed_addr`][] to reconstitute the original pointer including its /// later call [`with_exposed_provenance`][] to reconstitute the original pointer including its
/// provenance. (Reconstructing address space information, if required, is your responsibility.) /// provenance. (Reconstructing address space information, if required, is your responsibility.)
/// ///
/// Using this method means that code is *not* following [Strict /// Using this method means that code is *not* following [Strict
/// Provenance][super#strict-provenance] rules. Supporting /// Provenance][super#strict-provenance] rules. Supporting
/// [`from_exposed_addr`][] complicates specification and reasoning and may not be supported by /// [`with_exposed_provenance`][] 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 /// 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`][pointer::addr] wherever possible.
/// ///
/// On most platforms this will produce a value with the same bytes as the original pointer, /// 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 /// because all the bytes are dedicated to describing the address. Platforms which need to store
/// additional information in the pointer may not support this operation, since the 'expose' /// additional information in the pointer may not support this operation, since the 'expose'
/// side-effect which is required for [`from_exposed_addr`][] to work is typically not /// side-effect which is required for [`with_exposed_provenance`][] to work is typically not
/// available. /// available.
/// ///
/// It is unclear whether this method can be given a satisfying unambiguous specification. This /// It is unclear whether this method can be given a satisfying unambiguous specification. This
/// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance]. /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
/// ///
/// [`from_exposed_addr`]: from_exposed_addr /// [`with_exposed_provenance`]: with_exposed_provenance
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "exposed_provenance", issue = "95228")] #[unstable(feature = "exposed_provenance", issue = "95228")]

View file

@ -340,13 +340,13 @@
//! clear where a satisfying unambiguous semantics can be defined for Exposed Provenance. //! clear where a satisfying unambiguous semantics can be defined for Exposed Provenance.
//! Furthermore, Exposed Provenance will not work (well) with tools like [Miri] and [CHERI]. //! Furthermore, Exposed Provenance will not work (well) with tools like [Miri] and [CHERI].
//! //!
//! Exposed Provenance is provided by the [`expose_addr`] and [`from_exposed_addr`] methods, which //! Exposed Provenance is provided by the [`expose_addr`] and [`with_exposed_provenance`] methods, which
//! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like //! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like
//! [`addr`], but additionally adds the provenance of the pointer to a global list of 'exposed' //! [`addr`], but additionally adds the provenance of the pointer to a global list of 'exposed'
//! provenances. (This list is purely conceptual, it exists for the purpose of specifying Rust but //! provenances. (This list is purely conceptual, it exists for the purpose of specifying Rust but
//! is not materialized in actual executions, except in tools like [Miri].) [`from_exposed_addr`] //! is not materialized in actual executions, except in tools like [Miri].) [`with_exposed_provenance`]
//! can be used to construct a pointer with one of these previously 'exposed' provenances. //! can be used to construct a pointer with one of these previously 'exposed' provenances.
//! [`from_exposed_addr`] takes only `addr: usize` as arguments, so unlike in [`with_addr`] there is //! [`with_exposed_provenance`] takes only `addr: usize` as arguments, so unlike in [`with_addr`] there is
//! no indication of what the correct provenance for the returned pointer is -- and that is exactly //! no indication of what the correct provenance for the returned pointer is -- and that is exactly
//! what makes pointer-usize-pointer roundtrips so tricky to rigorously specify! There is no //! what makes pointer-usize-pointer roundtrips so tricky to rigorously specify! There is no
//! algorithm that decides which provenance will be used. You can think of this as "guessing" the //! algorithm that decides which provenance will be used. You can think of this as "guessing" the
@ -355,10 +355,10 @@
//! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will //! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will
//! be used, the program has undefined behavior. //! be used, the program has undefined behavior.
//! //!
//! Using [`expose_addr`] or [`from_exposed_addr`] (or the `as` casts) means that code is //! Using [`expose_addr`] or [`with_exposed_provenance`] (or the `as` casts) means that code is
//! *not* following Strict Provenance rules. The goal of the Strict Provenance experiment is to //! *not* following Strict Provenance rules. The goal of the Strict Provenance experiment is to
//! determine how far one can get in Rust without the use of [`expose_addr`] and //! determine how far one can get in Rust without the use of [`expose_addr`] and
//! [`from_exposed_addr`], and to encourage code to be written with Strict Provenance APIs only. //! [`with_exposed_provenance`], and to encourage code to be written with Strict Provenance APIs only.
//! Maximizing the amount of such code is a major win for avoiding specification complexity and to //! Maximizing the amount of such code is a major win for avoiding specification complexity and to
//! facilitate adoption of tools like [CHERI] and [Miri] that can be a big help in increasing the //! facilitate adoption of tools like [CHERI] and [Miri] that can be a big help in increasing the
//! confidence in (unsafe) Rust code. //! confidence in (unsafe) Rust code.
@ -375,7 +375,7 @@
//! [`addr`]: pointer::addr //! [`addr`]: pointer::addr
//! [`ptr::dangling`]: core::ptr::dangling //! [`ptr::dangling`]: core::ptr::dangling
//! [`expose_addr`]: pointer::expose_addr //! [`expose_addr`]: pointer::expose_addr
//! [`from_exposed_addr`]: from_exposed_addr //! [`with_exposed_provenance`]: with_exposed_provenance
//! [Miri]: https://github.com/rust-lang/miri //! [Miri]: https://github.com/rust-lang/miri
//! [CHERI]: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/ //! [CHERI]: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
//! [Strict Provenance]: https://github.com/rust-lang/rust/issues/95228 //! [Strict Provenance]: https://github.com/rust-lang/rust/issues/95228
@ -582,7 +582,7 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
/// little more than a usize address in disguise. /// little more than a usize address in disguise.
/// ///
/// This is different from `addr as *const T`, which creates a pointer that picks up a previously /// This is different from `addr as *const T`, which creates a pointer that picks up a previously
/// exposed provenance. See [`from_exposed_addr`] for more details on that operation. /// exposed provenance. See [`with_exposed_provenance`] for more details on that operation.
/// ///
/// This API and its claimed semantics are part of the Strict Provenance experiment, /// This API and its claimed semantics are part of the Strict Provenance experiment,
/// see the [module documentation][crate::ptr] for details. /// see the [module documentation][crate::ptr] for details.
@ -593,7 +593,7 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
pub const fn without_provenance<T>(addr: usize) -> *const T { pub const fn without_provenance<T>(addr: usize) -> *const T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
// We use transmute rather than a cast so tools like Miri can tell that this // We use transmute rather than a cast so tools like Miri can tell that this
// is *not* the same as from_exposed_addr. // is *not* the same as with_exposed_provenance.
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
// pointer). // pointer).
unsafe { mem::transmute(addr) } unsafe { mem::transmute(addr) }
@ -626,7 +626,7 @@ pub const fn dangling<T>() -> *const T {
/// little more than a usize address in disguise. /// little more than a usize address in disguise.
/// ///
/// This is different from `addr as *mut T`, which creates a pointer that picks up a previously /// This is different from `addr as *mut T`, which creates a pointer that picks up a previously
/// exposed provenance. See [`from_exposed_addr_mut`] for more details on that operation. /// exposed provenance. See [`with_exposed_provenance_mut`] for more details on that operation.
/// ///
/// This API and its claimed semantics are part of the Strict Provenance experiment, /// This API and its claimed semantics are part of the Strict Provenance experiment,
/// see the [module documentation][crate::ptr] for details. /// see the [module documentation][crate::ptr] for details.
@ -637,7 +637,7 @@ pub const fn dangling<T>() -> *const T {
pub const fn without_provenance_mut<T>(addr: usize) -> *mut T { pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
// We use transmute rather than a cast so tools like Miri can tell that this // We use transmute rather than a cast so tools like Miri can tell that this
// is *not* the same as from_exposed_addr. // is *not* the same as with_exposed_provenance.
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
// pointer). // pointer).
unsafe { mem::transmute(addr) } unsafe { mem::transmute(addr) }
@ -700,7 +700,7 @@ pub const fn dangling_mut<T>() -> *mut T {
#[unstable(feature = "exposed_provenance", issue = "95228")] #[unstable(feature = "exposed_provenance", issue = "95228")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
pub fn from_exposed_addr<T>(addr: usize) -> *const T pub fn with_exposed_provenance<T>(addr: usize) -> *const T
where where
T: Sized, T: Sized,
{ {
@ -740,7 +740,7 @@ where
#[unstable(feature = "exposed_provenance", issue = "95228")] #[unstable(feature = "exposed_provenance", issue = "95228")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T
where where
T: Sized, T: Sized,
{ {

View file

@ -171,7 +171,7 @@ impl<T: ?Sized> *mut T {
#[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
#[deprecated( #[deprecated(
since = "1.67.0", since = "1.67.0",
note = "replaced by the `ptr::from_exposed_addr_mut` function, or \ note = "replaced by the `ptr::with_exposed_provenance_mut` function, or \
update your code to follow the strict provenance rules using its APIs" update your code to follow the strict provenance rules using its APIs"
)] )]
#[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function #[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function
@ -194,7 +194,7 @@ impl<T: ?Sized> *mut T {
/// ///
/// If using those APIs is not possible because there is no way to preserve a pointer with the /// If using those APIs is not possible because there is no way to preserve a pointer with the
/// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
/// or [`expose_addr`][pointer::expose_addr] and [`from_exposed_addr`][from_exposed_addr] /// or [`expose_addr`][pointer::expose_addr] and [`with_exposed_provenance`][with_exposed_provenance]
/// instead. However, note that this makes your code less portable and less amenable to tools /// instead. However, note that this makes your code less portable and less amenable to tools
/// that check for compliance with the Rust memory model. /// that check for compliance with the Rust memory model.
/// ///
@ -218,30 +218,30 @@ impl<T: ?Sized> *mut T {
} }
/// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
/// use in [`from_exposed_addr`][]. /// use in [`with_exposed_provenance`][].
/// ///
/// This is equivalent to `self as usize`, which semantically discards *provenance* and /// This is equivalent to `self as usize`, which semantically discards *provenance* and
/// *address-space* information. Furthermore, this (like the `as` cast) has the implicit /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
/// side-effect of marking the provenance as 'exposed', so on platforms that support it you can /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
/// later call [`from_exposed_addr_mut`][] to reconstitute the original pointer including its /// later call [`with_exposed_provenance_mut`][] to reconstitute the original pointer including its
/// provenance. (Reconstructing address space information, if required, is your responsibility.) /// provenance. (Reconstructing address space information, if required, is your responsibility.)
/// ///
/// Using this method means that code is *not* following [Strict /// Using this method means that code is *not* following [Strict
/// Provenance][super#strict-provenance] rules. Supporting /// Provenance][super#strict-provenance] rules. Supporting
/// [`from_exposed_addr_mut`][] complicates specification and reasoning and may not be supported /// [`with_exposed_provenance_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 /// 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`][pointer::addr] wherever possible.
/// ///
/// On most platforms this will produce a value with the same bytes as the original pointer, /// 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 /// because all the bytes are dedicated to describing the address. Platforms which need to store
/// additional information in the pointer may not support this operation, since the 'expose' /// additional information in the pointer may not support this operation, since the 'expose'
/// side-effect which is required for [`from_exposed_addr_mut`][] to work is typically not /// side-effect which is required for [`with_exposed_provenance_mut`][] to work is typically not
/// available. /// available.
/// ///
/// It is unclear whether this method can be given a satisfying unambiguous specification. This /// It is unclear whether this method can be given a satisfying unambiguous specification. This
/// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance]. /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
/// ///
/// [`from_exposed_addr_mut`]: from_exposed_addr_mut /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "exposed_provenance", issue = "95228")] #[unstable(feature = "exposed_provenance", issue = "95228")]

View file

@ -51,13 +51,13 @@ pub trait SimdConstPtr: Copy + Sealed {
fn with_addr(self, addr: Self::Usize) -> Self; fn with_addr(self, addr: Self::Usize) -> Self;
/// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
/// in [`Self::from_exposed_addr`]. /// in [`Self::with_exposed_provenance`].
fn expose_addr(self) -> Self::Usize; fn expose_addr(self) -> Self::Usize;
/// Convert an address back to a pointer, picking up a previously "exposed" provenance. /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
/// ///
/// Equivalent to calling [`core::ptr::from_exposed_addr`] on each element. /// Equivalent to calling [`core::ptr::with_exposed_provenance`] on each element.
fn from_exposed_addr(addr: Self::Usize) -> Self; fn with_exposed_provenance(addr: Self::Usize) -> Self;
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
/// ///
@ -137,7 +137,7 @@ where
} }
#[inline] #[inline]
fn from_exposed_addr(addr: Self::Usize) -> Self { fn with_exposed_provenance(addr: Self::Usize) -> Self {
// Safety: `self` is a pointer vector // Safety: `self` is a pointer vector
unsafe { core::intrinsics::simd::simd_from_exposed_addr(addr) } unsafe { core::intrinsics::simd::simd_from_exposed_addr(addr) }
} }

View file

@ -48,13 +48,13 @@ pub trait SimdMutPtr: Copy + Sealed {
fn with_addr(self, addr: Self::Usize) -> Self; fn with_addr(self, addr: Self::Usize) -> Self;
/// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
/// in [`Self::from_exposed_addr`]. /// in [`Self::with_exposed_provenance`].
fn expose_addr(self) -> Self::Usize; fn expose_addr(self) -> Self::Usize;
/// Convert an address back to a pointer, picking up a previously "exposed" provenance. /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
/// ///
/// Equivalent to calling [`core::ptr::from_exposed_addr_mut`] on each element. /// Equivalent to calling [`core::ptr::with_exposed_provenance_mut`] on each element.
fn from_exposed_addr(addr: Self::Usize) -> Self; fn with_exposed_provenance(addr: Self::Usize) -> Self;
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
/// ///
@ -134,7 +134,7 @@ where
} }
#[inline] #[inline]
fn from_exposed_addr(addr: Self::Usize) -> Self { fn with_exposed_provenance(addr: Self::Usize) -> Self {
// Safety: `self` is a pointer vector // Safety: `self` is a pointer vector
unsafe { core::intrinsics::simd::simd_from_exposed_addr(addr) } unsafe { core::intrinsics::simd::simd_from_exposed_addr(addr) }
} }

View file

@ -80,10 +80,10 @@ mod const_ptr {
); );
} }
fn from_exposed_addr<const LANES: usize>() { fn with_exposed_provenance<const LANES: usize>() {
test_helpers::test_unary_elementwise( test_helpers::test_unary_elementwise(
&Simd::<*const u32, LANES>::from_exposed_addr, &Simd::<*const u32, LANES>::with_exposed_provenance,
&core::ptr::from_exposed_addr::<u32>, &core::ptr::with_exposed_provenance::<u32>,
&|_| true, &|_| true,
); );
} }
@ -103,10 +103,10 @@ mod mut_ptr {
); );
} }
fn from_exposed_addr<const LANES: usize>() { fn with_exposed_provenance<const LANES: usize>() {
test_helpers::test_unary_elementwise( test_helpers::test_unary_elementwise(
&Simd::<*mut u32, LANES>::from_exposed_addr, &Simd::<*mut u32, LANES>::with_exposed_provenance,
&core::ptr::from_exposed_addr_mut::<u32>, &core::ptr::with_exposed_provenance_mut::<u32>,
&|_| true, &|_| true,
); );
} }

View file

@ -389,7 +389,7 @@ pub(crate) unsafe fn map_memory<T>(
let result = a0; let result = a0;
if result == SyscallResult::MemoryRange as usize { if result == SyscallResult::MemoryRange as usize {
let start = core::ptr::from_exposed_addr_mut::<T>(a1); let start = core::ptr::with_exposed_provenance_mut::<T>(a1);
let len = a2 / core::mem::size_of::<T>(); let len = a2 / core::mem::size_of::<T>();
let end = unsafe { start.add(len) }; let end = unsafe { start.add(len) };
Ok(unsafe { core::slice::from_raw_parts_mut(start, len) }) Ok(unsafe { core::slice::from_raw_parts_mut(start, len) })

View file

@ -47,7 +47,7 @@ impl Thread {
extern "C" fn thread_start(main: usize) { extern "C" fn thread_start(main: usize) {
unsafe { unsafe {
// Finally, let's run some code. // Finally, let's run some code.
Box::from_raw(ptr::from_exposed_addr::<Box<dyn FnOnce()>>(main).cast_mut())(); Box::from_raw(ptr::with_exposed_provenance::<Box<dyn FnOnce()>>(main).cast_mut())();
// run all destructors // run all destructors
run_dtors(); run_dtors();

View file

@ -98,7 +98,7 @@ impl Thread {
}); });
unsafe extern "C" fn trampoline(exinf: isize) { unsafe extern "C" fn trampoline(exinf: isize) {
let p_inner: *mut ThreadInner = crate::ptr::from_exposed_addr_mut(exinf as usize); let p_inner: *mut ThreadInner = crate::ptr::with_exposed_provenance_mut(exinf as usize);
// Safety: `ThreadInner` is alive at this point // Safety: `ThreadInner` is alive at this point
let inner = unsafe { &*p_inner }; let inner = unsafe { &*p_inner };

View file

@ -49,7 +49,7 @@ fn tls_ptr_addr() -> *mut *mut u8 {
out(reg) tp, out(reg) tp,
); );
} }
core::ptr::from_exposed_addr_mut::<*mut u8>(tp) core::ptr::with_exposed_provenance_mut::<*mut u8>(tp)
} }
/// Create an area of memory that's unique per thread. This area will /// Create an area of memory that's unique per thread. This area will

View file

@ -9,13 +9,13 @@ pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
#[inline] #[inline]
pub unsafe fn set(key: Key, value: *mut u8) { pub unsafe fn set(key: Key, value: *mut u8) {
let key: *mut *mut u8 = core::ptr::from_exposed_addr_mut(key); let key: *mut *mut u8 = core::ptr::with_exposed_provenance_mut(key);
*key = value; *key = value;
} }
#[inline] #[inline]
pub unsafe fn get(key: Key) -> *mut u8 { pub unsafe fn get(key: Key) -> *mut u8 {
let key: *mut *mut u8 = core::ptr::from_exposed_addr_mut(key); let key: *mut *mut u8 = core::ptr::with_exposed_provenance_mut(key);
*key *key
} }

View file

@ -125,7 +125,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
// Can never have null landing pad for sjlj -- that would have // Can never have null landing pad for sjlj -- that would have
// been indicated by a -1 call site index. // been indicated by a -1 call site index.
// FIXME(strict provenance) // FIXME(strict provenance)
let lpad = ptr::from_exposed_addr((cs_lpad + 1) as usize); let lpad = ptr::with_exposed_provenance((cs_lpad + 1) as usize);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad)); return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
} }
} }

View file

@ -324,7 +324,7 @@ environment variable. We first document the most relevant and most commonly used
number of available CPUs is `1`. Note that this flag does not affect how miri handles threads in number of available CPUs is `1`. Note that this flag does not affect how miri handles threads in
any way. any way.
* `-Zmiri-permissive-provenance` disables the warning for integer-to-pointer casts and * `-Zmiri-permissive-provenance` disables the warning for integer-to-pointer casts and
[`ptr::from_exposed_addr`](https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html). [`ptr::with_exposed_provenance`](https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html).
This will necessarily miss some bugs as those operations are not efficiently and accurately This will necessarily miss some bugs as those operations are not efficiently and accurately
implementable in a sanitizer, but it will only miss bugs that concern memory/pointers which is implementable in a sanitizer, but it will only miss bugs that concern memory/pointers which is
subject to these operations. subject to these operations.

View file

@ -18,12 +18,12 @@ use reuse_pool::ReusePool;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ProvenanceMode { pub enum ProvenanceMode {
/// We support `expose_addr`/`from_exposed_addr` via "wildcard" provenance. /// We support `expose_addr`/`with_exposed_provenance` via "wildcard" provenance.
/// However, we want on `from_exposed_addr` to alert the user of the precision loss. /// However, we want on `with_exposed_provenance` to alert the user of the precision loss.
Default, Default,
/// Like `Default`, but without the warning. /// Like `Default`, but without the warning.
Permissive, Permissive,
/// We error on `from_exposed_addr`, ensuring no precision loss. /// We error on `with_exposed_provenance`, ensuring no precision loss.
Strict, Strict,
} }

View file

@ -65,7 +65,7 @@ impl fmt::Display for TerminationInfo {
Int2PtrWithStrictProvenance => Int2PtrWithStrictProvenance =>
write!( write!(
f, f,
"integer-to-pointer casts and `ptr::from_exposed_addr` are not supported with `-Zmiri-strict-provenance`" "integer-to-pointer casts and `ptr::with_exposed_provenance` are not supported with `-Zmiri-strict-provenance`"
), ),
StackedBorrowsUb { msg, .. } => write!(f, "{msg}"), StackedBorrowsUb { msg, .. } => write!(f, "{msg}"),
TreeBorrowsUb { title, .. } => write!(f, "{title}"), TreeBorrowsUb { title, .. } => write!(f, "{title}"),
@ -587,7 +587,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
( (
None, None,
format!( format!(
"This program is using integer-to-pointer casts or (equivalently) `ptr::from_exposed_addr`," "This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`,"
), ),
), ),
( (
@ -597,7 +597,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
( (
None, None,
format!( format!(
"See https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation." "See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation."
), ),
), ),
( (
@ -609,7 +609,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
( (
None, None,
format!( format!(
"You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics." "You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics."
), ),
), ),
( (

View file

@ -7,6 +7,6 @@ fn main() {
let x_usize: usize = x_ptr.addr(); let x_usize: usize = x_ptr.addr();
// Cast back an address that did *not* get exposed. // Cast back an address that did *not* get exposed.
let ptr = std::ptr::from_exposed_addr::<i32>(x_usize); let ptr = std::ptr::with_exposed_provenance::<i32>(x_usize);
assert_eq!(unsafe { *ptr }, 3); //~ ERROR: is a dangling pointer assert_eq!(unsafe { *ptr }, 3); //~ ERROR: is a dangling pointer
} }

View file

@ -3,5 +3,5 @@
fn main() { fn main() {
let addr = &0 as *const i32 as usize; let addr = &0 as *const i32 as usize;
let _ptr = std::ptr::from_exposed_addr::<i32>(addr); //~ ERROR: integer-to-pointer casts and `ptr::from_exposed_addr` are not supported let _ptr = std::ptr::with_exposed_provenance::<i32>(addr); //~ ERROR: integer-to-pointer casts and `ptr::with_exposed_provenance` are not supported
} }

View file

@ -1,8 +1,8 @@
error: unsupported operation: integer-to-pointer casts and `ptr::from_exposed_addr` are not supported with `-Zmiri-strict-provenance` error: unsupported operation: integer-to-pointer casts and `ptr::with_exposed_provenance` are not supported with `-Zmiri-strict-provenance`
--> $DIR/strict_provenance_cast.rs:LL:CC --> $DIR/strict_provenance_cast.rs:LL:CC
| |
LL | let _ptr = std::ptr::from_exposed_addr::<i32>(addr); LL | let _ptr = std::ptr::with_exposed_provenance::<i32>(addr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer casts and `ptr::from_exposed_addr` are not supported with `-Zmiri-strict-provenance` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer casts and `ptr::with_exposed_provenance` are not supported with `-Zmiri-strict-provenance`
| |
= help: use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead = help: use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead
= note: BACKTRACE: = note: BACKTRACE:

View file

@ -7,6 +7,6 @@ fn main() {
let mut x = 0; let mut x = 0;
let _fool = &mut x as *mut i32; // this would have fooled the old untagged pointer logic let _fool = &mut x as *mut i32; // this would have fooled the old untagged pointer logic
let addr = (&x as *const i32).expose_addr(); let addr = (&x as *const i32).expose_addr();
let ptr = std::ptr::from_exposed_addr_mut::<i32>(addr); let ptr = std::ptr::with_exposed_provenance_mut::<i32>(addr);
unsafe { *ptr = 0 }; //~ ERROR: /write access using <wildcard> .* no exposed tags have suitable permission in the borrow stack/ unsafe { *ptr = 0 }; //~ ERROR: /write access using <wildcard> .* no exposed tags have suitable permission in the borrow stack/
} }

View file

@ -4,11 +4,11 @@ warning: integer-to-pointer cast
LL | let r2 = ((r as usize) + 0) as *mut i32; LL | let r2 = ((r as usize) + 0) as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
| |
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::from_exposed_addr`, = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`,
= help: which means that Miri might miss pointer bugs in this program. = help: which means that Miri might miss pointer bugs in this program.
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
= help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead.
= help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics. = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics.
= help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning.
= note: BACKTRACE: = note: BACKTRACE:
= note: inside `into_raw` at $DIR/box.rs:LL:CC = note: inside `into_raw` at $DIR/box.rs:LL:CC

View file

@ -4,11 +4,11 @@ warning: integer-to-pointer cast
LL | let x: &Foo = unsafe { &*(16 as *const Foo) }; LL | let x: &Foo = unsafe { &*(16 as *const Foo) };
| ^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | ^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
| |
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::from_exposed_addr`, = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`,
= help: which means that Miri might miss pointer bugs in this program. = help: which means that Miri might miss pointer bugs in this program.
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
= help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead.
= help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics. = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics.
= help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning.
= note: BACKTRACE: = note: BACKTRACE:
= note: inside `main` at $DIR/extern_types.rs:LL:CC = note: inside `main` at $DIR/extern_types.rs:LL:CC

View file

@ -8,5 +8,5 @@ fn main() {
// Pointer casts // Pointer casts
let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast(); let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast();
let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr(); let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr();
let _ptrs = Simd::<*const i32, 4>::from_exposed_addr(addrs); let _ptrs = Simd::<*const i32, 4>::with_exposed_provenance(addrs);
} }

View file

@ -12,7 +12,7 @@ fn ptr_roundtrip_out_of_bounds() {
let x_usize = x_ptr.wrapping_offset(128).expose_addr(); let x_usize = x_ptr.wrapping_offset(128).expose_addr();
let ptr = ptr::from_exposed_addr::<i32>(x_usize).wrapping_offset(-128); let ptr = ptr::with_exposed_provenance::<i32>(x_usize).wrapping_offset(-128);
assert_eq!(unsafe { *ptr }, 3); assert_eq!(unsafe { *ptr }, 3);
} }
@ -27,7 +27,7 @@ fn ptr_roundtrip_confusion() {
let x_usize = x_ptr.expose_addr(); let x_usize = x_ptr.expose_addr();
let y_usize = y_ptr.expose_addr(); let y_usize = y_ptr.expose_addr();
let ptr = ptr::from_exposed_addr::<i32>(y_usize); let ptr = ptr::with_exposed_provenance::<i32>(y_usize);
let ptr = ptr.with_addr(x_usize); let ptr = ptr.with_addr(x_usize);
assert_eq!(unsafe { *ptr }, 0); assert_eq!(unsafe { *ptr }, 0);
} }
@ -39,7 +39,7 @@ fn ptr_roundtrip_imperfect() {
let x_usize = x_ptr.expose_addr() + 128; let x_usize = x_ptr.expose_addr() + 128;
let ptr = ptr::from_exposed_addr::<u8>(x_usize).wrapping_offset(-128); let ptr = ptr::with_exposed_provenance::<u8>(x_usize).wrapping_offset(-128);
assert_eq!(unsafe { *ptr }, 3); assert_eq!(unsafe { *ptr }, 3);
} }
@ -51,7 +51,7 @@ fn ptr_roundtrip_null() {
let null = x_null_ptr.expose_addr(); let null = x_null_ptr.expose_addr();
assert_eq!(null, 0); assert_eq!(null, 0);
let x_null_ptr_copy = ptr::from_exposed_addr::<i32>(null); // just a roundtrip, so has provenance of x (angelically) let x_null_ptr_copy = ptr::with_exposed_provenance::<i32>(null); // just a roundtrip, so has provenance of x (angelically)
let x_ptr_copy = x_null_ptr_copy.with_addr(x_ptr.addr()); // addr of x and provenance of x let x_ptr_copy = x_null_ptr_copy.with_addr(x_ptr.addr()); // addr of x and provenance of x
assert_eq!(unsafe { *x_ptr_copy }, 42); assert_eq!(unsafe { *x_ptr_copy }, 42);
} }

View file

@ -39,7 +39,7 @@ fn example(variant: bool) {
// 4 is the "obvious" choice (topmost tag, what we used to do with untagged pointers). // 4 is the "obvious" choice (topmost tag, what we used to do with untagged pointers).
// And indeed if `variant == true` it is the only possible choice. // And indeed if `variant == true` it is the only possible choice.
// But if `variant == false` then 2 is the only possible choice! // But if `variant == false` then 2 is the only possible choice!
let x_wildcard = ptr::from_exposed_addr_mut::<i32>(x_raw2_addr); let x_wildcard = ptr::with_exposed_provenance_mut::<i32>(x_raw2_addr);
if variant { if variant {
// If we picked 2, this will invalidate 3. // If we picked 2, this will invalidate 3.

View file

@ -4,11 +4,11 @@ warning: integer-to-pointer cast
LL | let wildcard = &root0 as *const Cell<i32> as usize as *const Cell<i32>; LL | let wildcard = &root0 as *const Cell<i32> as usize as *const Cell<i32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
| |
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::from_exposed_addr`, = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`,
= help: which means that Miri might miss pointer bugs in this program. = help: which means that Miri might miss pointer bugs in this program.
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
= help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead.
= help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics. = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics.
= help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning.
= note: BACKTRACE: = note: BACKTRACE:
= note: inside `main` at $DIR/issue-miri-2389.rs:LL:CC = note: inside `main` at $DIR/issue-miri-2389.rs:LL:CC

View file

@ -9,7 +9,7 @@ fn main() {
// Expose the allocation and use the exposed pointer, creating an unknown bottom // Expose the allocation and use the exposed pointer, creating an unknown bottom
unsafe { unsafe {
let p: *mut u8 = ptr::from_exposed_addr::<u8>(ptr.expose_addr()) as *mut u8; let p: *mut u8 = ptr::with_exposed_provenance::<u8>(ptr.expose_addr()) as *mut u8;
*p = 1; *p = 1;
} }

View file

@ -4,7 +4,7 @@ error: strict provenance disallows casting integer `usize` to pointer `*const u8
LL | let dangling = 16_usize as *const u8; LL | let dangling = 16_usize as *const u8;
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
note: the lint level is defined here note: the lint level is defined here
--> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9 --> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9
| |

View file

@ -24,10 +24,10 @@ fn main() {
let exposed_addr: V<usize> = simd_expose_addr(const_ptrs); let exposed_addr: V<usize> = simd_expose_addr(const_ptrs);
let from_exposed_addr: V<*mut i8> = simd_from_exposed_addr(exposed_addr); let with_exposed_provenance: V<*mut i8> = simd_from_exposed_addr(exposed_addr);
assert!(const_ptrs.0 == [ptr as *const u8, core::ptr::null()]); assert!(const_ptrs.0 == [ptr as *const u8, core::ptr::null()]);
assert!(exposed_addr.0 == [ptr as usize, 0]); assert!(exposed_addr.0 == [ptr as usize, 0]);
assert!(from_exposed_addr.0 == ptrs.0); assert!(with_exposed_provenance.0 == ptrs.0);
} }
} }