rename expose_addr to expose_provenance

This commit is contained in:
joboet 2024-04-03 15:17:00 +02:00
parent 99c42d2340
commit 989660c3e6
No known key found for this signature in database
GPG Key ID: 704E0149B0194B3C
49 changed files with 105 additions and 99 deletions

View File

@ -2261,7 +2261,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
} }
CastKind::PointerExposeAddress => { CastKind::PointerExposeProvenance => {
let ty_from = op.ty(body, tcx); let ty_from = op.ty(body, tcx);
let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_from = CastTy::from_ty(ty_from);
let cast_ty_to = CastTy::from_ty(*ty); let cast_ty_to = CastTy::from_ty(*ty);
@ -2271,7 +2271,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
span_mirbug!( span_mirbug!(
self, self,
rvalue, rvalue,
"Invalid PointerExposeAddress cast {:?} -> {:?}", "Invalid PointerExposeProvenance cast {:?} -> {:?}",
ty_from, ty_from,
ty ty
) )

View File

@ -649,7 +649,7 @@ fn codegen_stmt<'tcx>(
| CastKind::IntToFloat | CastKind::IntToFloat
| CastKind::FnPtrToPtr | CastKind::FnPtrToPtr
| CastKind::PtrToPtr | CastKind::PtrToPtr
| CastKind::PointerExposeAddress | CastKind::PointerExposeProvenance
| CastKind::PointerWithExposedProvenance, | CastKind::PointerWithExposedProvenance,
ref operand, ref operand,
to_ty, to_ty,

View File

@ -965,7 +965,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
}); });
} }
sym::simd_expose_addr | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => { sym::simd_expose_provenance | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => {
intrinsic_args!(fx, args => (arg); intrinsic); intrinsic_args!(fx, args => (arg); intrinsic);
ret.write_cvalue_transmute(fx, arg); ret.write_cvalue_transmute(fx, arg);
} }

View File

@ -2111,7 +2111,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
return Ok(args[0].immediate()); return Ok(args[0].immediate());
} }
if name == sym::simd_expose_addr { if name == sym::simd_expose_provenance {
let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn); let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
require!( require!(
in_len == out_len, in_len == out_len,

View File

@ -405,7 +405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty)); let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty));
let val = match *kind { let val = match *kind {
mir::CastKind::PointerExposeAddress => { mir::CastKind::PointerExposeProvenance => {
assert!(bx.cx().is_backend_immediate(cast)); assert!(bx.cx().is_backend_immediate(cast));
let llptr = operand.immediate(); let llptr = operand.immediate();
let llcast_ty = bx.cx().immediate_backend_type(cast); let llcast_ty = bx.cx().immediate_backend_type(cast);

View File

@ -34,9 +34,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.unsize_into(src, cast_layout, dest)?; self.unsize_into(src, cast_layout, dest)?;
} }
CastKind::PointerExposeAddress => { CastKind::PointerExposeProvenance => {
let src = self.read_immediate(src)?; let src = self.read_immediate(src)?;
let res = self.pointer_expose_address_cast(&src, cast_layout)?; let res = self.pointer_expose_provenance_cast(&src, cast_layout)?;
self.write_immediate(*res, dest)?; self.write_immediate(*res, dest)?;
} }
@ -225,7 +225,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
} }
pub fn pointer_expose_address_cast( pub fn pointer_expose_provenance_cast(
&mut self, &mut self,
src: &ImmTy<'tcx, M::Provenance>, src: &ImmTy<'tcx, M::Provenance>,
cast_to: TyAndLayout<'tcx>, cast_to: TyAndLayout<'tcx>,

View File

@ -544,7 +544,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// Unsizing is implemented for CTFE. // Unsizing is implemented for CTFE.
} }
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
self.check_op(ops::RawPtrToIntCast); self.check_op(ops::RawPtrToIntCast);
} }
Rvalue::Cast(CastKind::PointerWithExposedProvenance, _, _) => { Rvalue::Cast(CastKind::PointerWithExposedProvenance, _, _) => {

View File

@ -1077,7 +1077,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
} }
// FIXME: Add Checks for these // FIXME: Add Checks for these
CastKind::PointerWithExposedProvenance CastKind::PointerWithExposedProvenance
| CastKind::PointerExposeAddress | CastKind::PointerExposeProvenance
| CastKind::PointerCoercion(_) => {} | CastKind::PointerCoercion(_) => {}
CastKind::IntToInt | CastKind::IntToFloat => { CastKind::IntToInt | CastKind::IntToFloat => {
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool(); let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();

View File

@ -627,7 +627,7 @@ pub fn check_intrinsic_type(
sym::simd_cast sym::simd_cast
| sym::simd_as | sym::simd_as
| sym::simd_cast_ptr | sym::simd_cast_ptr
| sym::simd_expose_addr | sym::simd_expose_provenance
| sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)), | sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)),
sym::simd_bitmask => (2, 0, vec![param(0)], param(1)), sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
sym::simd_select | sym::simd_select_bitmask => { sym::simd_select | sym::simd_select_bitmask => {

View File

@ -91,7 +91,7 @@ hir_typeck_lossy_provenance_int2ptr =
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}`
.suggestion = use `.addr()` to obtain the address of a pointer .suggestion = use `.addr()` to obtain the address of a pointer
.help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
hir_typeck_method_call_on_unknown_raw_pointee = hir_typeck_method_call_on_unknown_raw_pointee =
cannot call a method on a raw pointer with an unknown pointee type cannot call a method on a raw pointer with an unknown pointee type

View File

@ -2797,17 +2797,17 @@ declare_lint! {
/// Since this cast is lossy, it is considered good style to use the /// Since this cast is lossy, it is considered good style to use the
/// [`ptr::addr`] method instead, which has a similar effect, but doesn't /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
/// "expose" the pointer provenance. This improves optimisation potential. /// "expose" the pointer provenance. This improves optimisation potential.
/// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information
/// about exposing pointer provenance. /// about exposing pointer provenance.
/// ///
/// If your code can't comply with strict provenance and needs to expose /// If your code can't comply with strict provenance and needs to expose
/// the provenance, then there is [`ptr::expose_addr`] as an escape hatch, /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch,
/// which preserves the behaviour of `as usize` casts while being explicit /// which preserves the behaviour of `as usize` casts while being explicit
/// about the semantics. /// about the semantics.
/// ///
/// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
/// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr
/// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_addr /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance
pub LOSSY_PROVENANCE_CASTS, pub LOSSY_PROVENANCE_CASTS,
Allow, Allow,
"a lossy pointer to integer cast is used", "a lossy pointer to integer cast is used",

View File

@ -409,7 +409,7 @@ impl<'tcx> Rvalue<'tcx> {
// Pointer to int casts may be side-effects due to exposing the provenance. // Pointer to int casts may be side-effects due to exposing the provenance.
// While the model is undecided, we should be conservative. See // While the model is undecided, we should be conservative. See
// <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html> // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false, Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => false,
Rvalue::Use(_) Rvalue::Use(_)
| Rvalue::CopyForDeref(_) | Rvalue::CopyForDeref(_)

View File

@ -1309,8 +1309,8 @@ pub enum Rvalue<'tcx> {
pub enum CastKind { pub enum CastKind {
/// An exposing pointer to address cast. A cast between a pointer and an integer type, or /// An exposing pointer to address cast. A cast between a pointer and an integer type, or
/// between a function pointer and an integer type. /// between a function pointer and an integer type.
/// See the docs on `expose_addr` for more details. /// See the docs on `expose_provenance` for more details.
PointerExposeAddress, PointerExposeProvenance,
/// 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 `with_exposed_provenance` for more details. /// See the docs on `with_exposed_provenance` for more details.
PointerWithExposedProvenance, PointerWithExposedProvenance,

View File

@ -83,7 +83,7 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin
let cast = CastTy::from_ty(cast_ty); let cast = CastTy::from_ty(cast_ty);
let cast_kind = match (from, cast) { let cast_kind = match (from, cast) {
(Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => { (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
mir::CastKind::PointerExposeAddress mir::CastKind::PointerExposeProvenance
} }
(Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
(_, Some(CastTy::DynStar)) => mir::CastKind::DynStar, (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,

View File

@ -434,7 +434,7 @@ impl<'tcx> Validator<'_, 'tcx> {
Rvalue::ThreadLocalRef(_) => return Err(Unpromotable), Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
// ptr-to-int casts are not possible in consts and thus not promotable // ptr-to-int casts are not possible in consts and thus not promotable
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable), Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => return Err(Unpromotable),
// all other casts including int-to-ptr casts are fine, they just use the integer value // all other casts including int-to-ptr casts are fine, they just use the integer value
// at pointer type. // at pointer type.

View File

@ -985,7 +985,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t
let locals = local_decls_for_sig(&sig, span); let locals = local_decls_for_sig(&sig, span);
let source_info = SourceInfo::outermost(span); let source_info = SourceInfo::outermost(span);
// FIXME: use `expose_addr` once we figure out whether function pointers have meaningful provenance. // FIXME: use `expose_provenance` once we figure out whether function pointers have meaningful provenance.
let rvalue = Rvalue::Cast( let rvalue = Rvalue::Cast(
CastKind::FnPtrToPtr, CastKind::FnPtrToPtr,
Operand::Move(Place::from(Local::new(1))), Operand::Move(Place::from(Local::new(1))),

View File

@ -267,7 +267,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
fn stable(&self, tables: &mut Tables<'_>) -> Self::T { fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
use rustc_middle::mir::CastKind::*; use rustc_middle::mir::CastKind::*;
match self { match self {
PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress, PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
DynStar => stable_mir::mir::CastKind::DynStar, DynStar => stable_mir::mir::CastKind::DynStar,

View File

@ -1659,7 +1659,7 @@ symbols! {
simd_cttz, simd_cttz,
simd_div, simd_div,
simd_eq, simd_eq,
simd_expose_addr, simd_expose_provenance,
simd_extract, simd_extract,
simd_fabs, simd_fabs,
simd_fcos, simd_fcos,

View File

@ -971,6 +971,7 @@ pub enum PointerCoercion {
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum CastKind { pub enum CastKind {
// FIXME(smir-rename): rename this to PointerExposeProvenance
PointerExposeAddress, PointerExposeAddress,
PointerWithExposedProvenance, PointerWithExposedProvenance,
PointerCoercion(PointerCoercion), PointerCoercion(PointerCoercion),

View File

@ -2438,8 +2438,8 @@ impl Display for char {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Pointer for *const T { impl<T: ?Sized> Pointer for *const T {
fn fmt(&self, f: &mut Formatter<'_>) -> Result { fn fmt(&self, f: &mut Formatter<'_>) -> Result {
// Cast is needed here because `.expose_addr()` requires `T: Sized`. // Cast is needed here because `.expose_provenance()` requires `T: Sized`.
pointer_fmt_inner((*self as *const ()).expose_addr(), f) pointer_fmt_inner((*self as *const ()).expose_provenance(), f)
} }
} }

View File

@ -540,6 +540,10 @@ extern "rust-intrinsic" {
/// `T` must be a vector of pointers. /// `T` must be a vector of pointers.
/// ///
/// `U` must be a vector of `usize` with the same length as `T`. /// `U` must be a vector of `usize` with the same length as `T`.
#[cfg(not(bootstrap))]
#[rustc_nounwind]
pub fn simd_expose_provenance<T, U>(ptr: T) -> U;
#[cfg(bootstrap)]
#[rustc_nounwind] #[rustc_nounwind]
pub fn simd_expose_addr<T, U>(ptr: T) -> U; pub fn simd_expose_addr<T, U>(ptr: T) -> U;
@ -660,5 +664,7 @@ extern "rust-intrinsic" {
pub fn simd_flog<T>(a: T) -> T; pub fn simd_flog<T>(a: T) -> T;
} }
#[cfg(bootstrap)]
pub use simd_expose_addr as simd_expose_provenance;
#[cfg(bootstrap)] #[cfg(bootstrap)]
pub use simd_from_exposed_addr as simd_with_exposed_provenance; pub use simd_from_exposed_addr as simd_with_exposed_provenance;

View File

@ -136,7 +136,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 `expose_addr` method, or update your code \ note = "replaced by the `expose_provenance` method, or update your code \
to follow the strict provenance rules using its APIs" to follow the strict provenance rules using its APIs"
)] )]
#[inline(always)] #[inline(always)]
@ -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 [`with_exposed_provenance`][with_exposed_provenance] /// or [`expose_provenance`][pointer::expose_provenance] 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.
/// ///
@ -210,8 +210,8 @@ impl<T: ?Sized> *const T {
unsafe { mem::transmute(self.cast::<()>()) } unsafe { mem::transmute(self.cast::<()>()) }
} }
/// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future /// Exposes the "provenance" part of the pointer for future use in
/// use in [`with_exposed_provenance`][]. /// [`with_exposed_provenance`][] and returns the "address" portion.
/// ///
/// 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
@ -238,7 +238,7 @@ impl<T: ?Sized> *const T {
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "exposed_provenance", issue = "95228")] #[unstable(feature = "exposed_provenance", issue = "95228")]
pub fn expose_addr(self) -> usize { pub fn expose_provenance(self) -> usize {
// 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.
self.cast::<()>() as usize self.cast::<()>() as usize
} }

View File

@ -340,8 +340,8 @@
//! 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 [`with_exposed_provenance`] methods, which //! Exposed Provenance is provided by the [`expose_provenance`] and [`with_exposed_provenance`] methods,
//! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like //! which are meant to replace `as` casts between pointers and integers. [`expose_provenance`] 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].) [`with_exposed_provenance`] //! is not materialized in actual executions, except in tools like [Miri].) [`with_exposed_provenance`]
@ -355,9 +355,9 @@
//! 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 [`with_exposed_provenance`] (or the `as` casts) means that code is //! Using [`expose_provenance`] 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_provenance`] and
//! [`with_exposed_provenance`], 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
@ -374,7 +374,7 @@
//! [`map_addr`]: pointer::map_addr //! [`map_addr`]: pointer::map_addr
//! [`addr`]: pointer::addr //! [`addr`]: pointer::addr
//! [`ptr::dangling`]: core::ptr::dangling //! [`ptr::dangling`]: core::ptr::dangling
//! [`expose_addr`]: pointer::expose_addr //! [`expose_provenance`]: pointer::expose_provenance
//! [`with_exposed_provenance`]: with_exposed_provenance //! [`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/
@ -663,7 +663,7 @@ pub const fn dangling_mut<T>() -> *mut T {
/// ///
/// This is a more rigorously specified alternative to `addr as *const T`. The provenance of the /// This is a more rigorously specified alternative to `addr as *const T`. The provenance of the
/// returned pointer is that of *any* pointer that was previously exposed by passing it to /// returned pointer is that of *any* pointer that was previously exposed by passing it to
/// [`expose_addr`][pointer::expose_addr], or a `ptr as usize` cast. In addition, memory which is /// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory which is
/// outside the control of the Rust abstract machine (MMIO registers, for example) is always /// outside the control of the Rust abstract machine (MMIO registers, for example) is always
/// considered to be exposed, so long as this memory is disjoint from memory that will be used by /// considered to be exposed, so long as this memory is disjoint from memory that will be used by
/// the abstract machine such as the stack, heap, and statics. /// the abstract machine such as the stack, heap, and statics.
@ -711,7 +711,7 @@ where
/// ///
/// This is a more rigorously specified alternative to `addr as *mut T`. The provenance of the /// This is a more rigorously specified alternative to `addr as *mut T`. The provenance of the
/// returned pointer is that of *any* pointer that was previously passed to /// returned pointer is that of *any* pointer that was previously passed to
/// [`expose_addr`][pointer::expose_addr] or a `ptr as usize` cast. If there is no previously /// [`expose_provenance`][pointer::expose_provenance] or a `ptr as usize` cast. If there is no previously
/// 'exposed' provenance that justifies the way this pointer will be used, the program has undefined /// 'exposed' provenance that justifies the way this pointer will be used, the program has undefined
/// behavior. Note that there is no algorithm that decides which provenance will be used. You can /// behavior. Note that there is no algorithm that decides which provenance will be used. You can
/// think of this as "guessing" the right provenance, and the guess will be "maximally in your /// think of this as "guessing" the right provenance, and the guess will be "maximally in your

View File

@ -142,7 +142,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 `expose_addr` method, or update your code \ note = "replaced by the `expose_provenance` method, or update your code \
to follow the strict provenance rules using its APIs" to follow the strict provenance rules using its APIs"
)] )]
#[inline(always)] #[inline(always)]
@ -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 [`with_exposed_provenance`][with_exposed_provenance] /// or [`expose_provenance`][pointer::expose_provenance] 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.
/// ///
@ -217,8 +217,8 @@ impl<T: ?Sized> *mut T {
unsafe { mem::transmute(self.cast::<()>()) } unsafe { mem::transmute(self.cast::<()>()) }
} }
/// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future /// Exposes the "provenance" part of the pointer for future use in
/// use in [`with_exposed_provenance`][]. /// [`with_exposed_provenance`][] and returns the "address" portion.
/// ///
/// 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
@ -242,10 +242,9 @@ impl<T: ?Sized> *mut T {
/// 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].
/// ///
/// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
#[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "exposed_provenance", issue = "95228")] #[unstable(feature = "exposed_provenance", issue = "95228")]
pub fn expose_addr(self) -> usize { pub fn expose_provenance(self) -> usize {
// 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.
self.cast::<()>() as usize self.cast::<()>() as usize
} }

View File

@ -50,9 +50,9 @@ pub trait SimdConstPtr: Copy + Sealed {
/// Equivalent to calling [`pointer::with_addr`] on each element. /// Equivalent to calling [`pointer::with_addr`] on each element.
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 /// Exposes the "provenance" part of the pointer for future use in
/// in [`Self::with_exposed_provenance`]. /// [`Self::with_exposed_provenance`] and returns the "address" portion.
fn expose_addr(self) -> Self::Usize; fn expose_provenance(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.
/// ///
@ -131,9 +131,9 @@ where
} }
#[inline] #[inline]
fn expose_addr(self) -> Self::Usize { fn expose_provenance(self) -> Self::Usize {
// Safety: `self` is a pointer vector // Safety: `self` is a pointer vector
unsafe { core::intrinsics::simd::simd_expose_addr(self) } unsafe { core::intrinsics::simd::simd_expose_provenance(self) }
} }
#[inline] #[inline]

View File

@ -47,9 +47,9 @@ pub trait SimdMutPtr: Copy + Sealed {
/// Equivalent to calling [`pointer::with_addr`] on each element. /// Equivalent to calling [`pointer::with_addr`] on each element.
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 /// Exposes the "provenance" part of the pointer for future use in
/// in [`Self::with_exposed_provenance`]. /// [`Self::with_exposed_provenance`] and returns the "address" portion.
fn expose_addr(self) -> Self::Usize; fn expose_provenance(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.
/// ///
@ -128,9 +128,9 @@ where
} }
#[inline] #[inline]
fn expose_addr(self) -> Self::Usize { fn expose_provenance(self) -> Self::Usize {
// Safety: `self` is a pointer vector // Safety: `self` is a pointer vector
unsafe { core::intrinsics::simd::simd_expose_addr(self) } unsafe { core::intrinsics::simd::simd_expose_provenance(self) }
} }
#[inline] #[inline]

View File

@ -32,10 +32,10 @@ macro_rules! common_tests {
); );
} }
fn expose_addr<const LANES: usize>() { fn expose_provenance<const LANES: usize>() {
test_helpers::test_unary_elementwise( test_helpers::test_unary_elementwise(
&Simd::<*$constness u32, LANES>::expose_addr, &Simd::<*$constness u32, LANES>::expose_provenance,
&<*$constness u32>::expose_addr, &<*$constness u32>::expose_provenance,
&|_| true, &|_| true,
); );
} }

View File

@ -29,7 +29,7 @@ impl Thread {
let p = Box::into_raw(Box::new(p)); let p = Box::into_raw(Box::new(p));
let tid = abi::spawn2( let tid = abi::spawn2(
thread_start, thread_start,
p.expose_addr(), p.expose_provenance(),
abi::Priority::into(abi::NORMAL_PRIO), abi::Priority::into(abi::NORMAL_PRIO),
stack, stack,
core_id, core_id,

View File

@ -181,7 +181,7 @@ impl Thread {
abi::acre_tsk(&abi::T_CTSK { abi::acre_tsk(&abi::T_CTSK {
// Activate this task immediately // Activate this task immediately
tskatr: abi::TA_ACT, tskatr: abi::TA_ACT,
exinf: p_inner.as_ptr().expose_addr() as abi::EXINF, exinf: p_inner.as_ptr().expose_provenance() as abi::EXINF,
// The entry point // The entry point
task: Some(trampoline), task: Some(trampoline),
// Inherit the calling task's base priority // Inherit the calling task's base priority

View File

@ -149,7 +149,7 @@ fn check_rvalue<'tcx>(
Err((span, "unsizing casts are not allowed in const fn".into())) Err((span, "unsizing casts are not allowed in const fn".into()))
} }
}, },
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
Err((span, "casting pointers to ints is unstable in const fn".into())) Err((span, "casting pointers to ints is unstable in const fn".into()))
}, },
Rvalue::Cast(CastKind::DynStar, _, _) => { Rvalue::Cast(CastKind::DynStar, _, _) => {

View File

@ -18,8 +18,8 @@ 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`/`with_exposed_provenance` via "wildcard" provenance. /// We support `expose_provenance`/`with_exposed_provenance` via "wildcard" provenance.
/// However, we want on `with_exposed_provenance` to alert the user of the precision loss. /// However, we warn 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,

View File

@ -514,7 +514,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
dest.transmute(this.machine.layouts.uint(dest.layout.size).unwrap(), this)?; dest.transmute(this.machine.layouts.uint(dest.layout.size).unwrap(), this)?;
this.write_int(res, &dest)?; this.write_int(res, &dest)?;
} }
"cast" | "as" | "cast_ptr" | "expose_addr" | "with_exposed_provenance" => { "cast" | "as" | "cast_ptr" | "expose_provenance" | "with_exposed_provenance" => {
let [op] = check_arg_count(args)?; let [op] = check_arg_count(args)?;
let (op, op_len) = this.operand_to_simd(op)?; let (op, op_len) = this.operand_to_simd(op)?;
let (dest, dest_len) = this.mplace_to_simd(dest)?; let (dest, dest_len) = this.mplace_to_simd(dest)?;
@ -524,7 +524,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let unsafe_cast = intrinsic_name == "cast"; let unsafe_cast = intrinsic_name == "cast";
let safe_cast = intrinsic_name == "as"; let safe_cast = intrinsic_name == "as";
let ptr_cast = intrinsic_name == "cast_ptr"; let ptr_cast = intrinsic_name == "cast_ptr";
let expose_cast = intrinsic_name == "expose_addr"; let expose_cast = intrinsic_name == "expose_provenance";
let from_exposed_cast = intrinsic_name == "with_exposed_provenance"; let from_exposed_cast = intrinsic_name == "with_exposed_provenance";
for i in 0..dest_len { for i in 0..dest_len {
@ -557,7 +557,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.ptr_to_ptr(&op, dest.layout)?, this.ptr_to_ptr(&op, dest.layout)?,
// Ptr/Int casts // Ptr/Int casts
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => (ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
this.pointer_expose_address_cast(&op, dest.layout)?, this.pointer_expose_provenance_cast(&op, dest.layout)?,
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => (ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
this.pointer_with_exposed_provenance_cast(&op, dest.layout)?, this.pointer_with_exposed_provenance_cast(&op, dest.layout)?,
// Error otherwise // Error otherwise

View File

@ -4,6 +4,6 @@
fn main() { fn main() {
let x = 42; let x = 42;
let xptr = &x as *const i32; let xptr = &x as *const i32;
let xptr_invalid = std::ptr::without_provenance::<i32>(xptr.expose_addr()); let xptr_invalid = std::ptr::without_provenance::<i32>(xptr.expose_provenance());
let _val = unsafe { *xptr_invalid }; //~ ERROR: is a dangling pointer let _val = unsafe { *xptr_invalid }; //~ ERROR: is a dangling pointer
} }

View File

@ -6,7 +6,7 @@
fn main() { 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_provenance();
let ptr = std::ptr::with_exposed_provenance_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

@ -7,6 +7,6 @@ use std::simd::prelude::*;
fn main() { 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_provenance();
let _ptrs = Simd::<*const i32, 4>::with_exposed_provenance(addrs); let _ptrs = Simd::<*const i32, 4>::with_exposed_provenance(addrs);
} }

View File

@ -10,7 +10,7 @@ fn ptr_roundtrip_out_of_bounds() {
let x: i32 = 3; let x: i32 = 3;
let x_ptr = &x as *const i32; let x_ptr = &x as *const i32;
let x_usize = x_ptr.wrapping_offset(128).expose_addr(); let x_usize = x_ptr.wrapping_offset(128).expose_provenance();
let ptr = ptr::with_exposed_provenance::<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);
@ -24,8 +24,8 @@ fn ptr_roundtrip_confusion() {
let x_ptr = &x as *const i32; let x_ptr = &x as *const i32;
let y_ptr = &y as *const i32; let y_ptr = &y as *const i32;
let x_usize = x_ptr.expose_addr(); let x_usize = x_ptr.expose_provenance();
let y_usize = y_ptr.expose_addr(); let y_usize = y_ptr.expose_provenance();
let ptr = ptr::with_exposed_provenance::<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);
@ -37,7 +37,7 @@ fn ptr_roundtrip_imperfect() {
let x: u8 = 3; let x: u8 = 3;
let x_ptr = &x as *const u8; let x_ptr = &x as *const u8;
let x_usize = x_ptr.expose_addr() + 128; let x_usize = x_ptr.expose_provenance() + 128;
let ptr = ptr::with_exposed_provenance::<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);
@ -48,7 +48,7 @@ fn ptr_roundtrip_null() {
let x = &42; let x = &42;
let x_ptr = x as *const i32; let x_ptr = x as *const i32;
let x_null_ptr = x_ptr.with_addr(0); // addr 0, but still the provenance of x let x_null_ptr = x_ptr.with_addr(0); // addr 0, but still the provenance of x
let null = x_null_ptr.expose_addr(); let null = x_null_ptr.expose_provenance();
assert_eq!(null, 0); assert_eq!(null, 0);
let x_null_ptr_copy = ptr::with_exposed_provenance::<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)

View File

@ -17,7 +17,7 @@ fn example(variant: bool) {
unsafe { unsafe {
fn not_so_innocent(x: &mut u32) -> usize { fn not_so_innocent(x: &mut u32) -> usize {
let x_raw4 = x as *mut u32; let x_raw4 = x as *mut u32;
x_raw4.expose_addr() x_raw4.expose_provenance()
} }
let mut c = 42u32; let mut c = 42u32;
@ -26,7 +26,7 @@ fn example(variant: bool) {
// stack: [..., Unique(1)] // stack: [..., Unique(1)]
let x_raw2 = x_unique1 as *mut u32; let x_raw2 = x_unique1 as *mut u32;
let x_raw2_addr = x_raw2.expose_addr(); let x_raw2_addr = x_raw2.expose_provenance();
// stack: [..., Unique(1), SharedRW(2)] // stack: [..., Unique(1), SharedRW(2)]
let x_unique3 = &mut *x_raw2; let x_unique3 = &mut *x_raw2;

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::with_exposed_provenance::<u8>(ptr.expose_addr()) as *mut u8; let p: *mut u8 = ptr::with_exposed_provenance::<u8>(ptr.expose_provenance()) as *mut u8;
*p = 1; *p = 1;
} }

View File

@ -19,7 +19,7 @@
StorageLive(_3); StorageLive(_3);
_3 = const main::FOO; _3 = const main::FOO;
_2 = &raw const (*_3); _2 = &raw const (*_3);
_1 = move _2 as usize (PointerExposeAddress); _1 = move _2 as usize (PointerExposeProvenance);
StorageDead(_2); StorageDead(_2);
StorageDead(_3); StorageDead(_3);
StorageLive(_4); StorageLive(_4);

View File

@ -19,7 +19,7 @@
StorageLive(_3); StorageLive(_3);
_3 = const main::FOO; _3 = const main::FOO;
_2 = &raw const (*_3); _2 = &raw const (*_3);
_1 = move _2 as usize (PointerExposeAddress); _1 = move _2 as usize (PointerExposeProvenance);
StorageDead(_2); StorageDead(_2);
StorageDead(_3); StorageDead(_3);
StorageLive(_4); StorageLive(_4);

View File

@ -4,12 +4,12 @@
#[inline(never)] #[inline(never)]
fn read(_: usize) { } fn read(_: usize) { }
// EMIT_MIR pointer_expose_address.main.GVN.diff // EMIT_MIR pointer_expose_provenance.main.GVN.diff
fn main() { fn main() {
// CHECK-LABEL: fn main( // CHECK-LABEL: fn main(
// CHECK: [[ptr:_.*]] = const main::FOO; // CHECK: [[ptr:_.*]] = const main::FOO;
// CHECK: [[ref:_.*]] = &raw const (*[[ptr]]); // CHECK: [[ref:_.*]] = &raw const (*[[ptr]]);
// CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeAddress); // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeProvenance);
// CHECK: = read([[x]]) // CHECK: = read([[x]])
const FOO: &i32 = &1; const FOO: &i32 = &1;
let x = FOO as *const i32 as usize; let x = FOO as *const i32 as usize;

View File

@ -14,7 +14,7 @@
StorageLive(_2); StorageLive(_2);
StorageLive(_3); StorageLive(_3);
_3 = main as fn() (PointerCoercion(ReifyFnPointer)); _3 = main as fn() (PointerCoercion(ReifyFnPointer));
_2 = move _3 as usize (PointerExposeAddress); _2 = move _3 as usize (PointerExposeProvenance);
StorageDead(_3); StorageDead(_3);
_1 = move _2 as *const fn() (PointerWithExposedProvenance); _1 = move _2 as *const fn() (PointerWithExposedProvenance);
StorageDead(_2); StorageDead(_2);

View File

@ -4,7 +4,7 @@
fn main() { fn main() {
// CHECK-LABEL: fn main( // CHECK-LABEL: fn main(
// CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer)); // CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer));
// CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeAddress); // CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeProvenance);
// CHECK: [[back:_.*]] = move [[addr]] as *const fn() (PointerWithExposedProvenance); // CHECK: [[back:_.*]] = move [[addr]] as *const fn() (PointerWithExposedProvenance);
let _ = main as usize as *const fn(); let _ = main as usize as *const fn();
} }

View File

@ -19,12 +19,12 @@
StorageLive(_2); StorageLive(_2);
StorageLive(_3); StorageLive(_3);
_3 = _1; _3 = _1;
_2 = move _3 as usize (PointerExposeAddress); _2 = move _3 as usize (PointerExposeProvenance);
StorageDead(_3); StorageDead(_3);
StorageLive(_4); StorageLive(_4);
StorageLive(_5); StorageLive(_5);
_5 = _1; _5 = _1;
_4 = move _5 as isize (PointerExposeAddress); _4 = move _5 as isize (PointerExposeProvenance);
StorageDead(_5); StorageDead(_5);
_0 = const (); _0 = const ();
StorageDead(_4); StorageDead(_4);

View File

@ -5,8 +5,8 @@
// EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff // EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
fn pointer_to_int(p: *mut i32) { fn pointer_to_int(p: *mut i32) {
// CHECK-LABEL: fn pointer_to_int( // CHECK-LABEL: fn pointer_to_int(
// CHECK: {{_.*}} = {{.*}} as usize (PointerExposeAddress); // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeProvenance);
// CHECK: {{_.*}} = {{.*}} as isize (PointerExposeAddress); // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeProvenance);
let _x = p as usize; let _x = p as usize;
let _y = p as isize; let _y = p as isize;
} }

View File

@ -1,7 +1,7 @@
- // MIR for `expose_addr` before SimplifyLocals-before-const-prop - // MIR for `expose_provenance` before SimplifyLocals-before-const-prop
+ // MIR for `expose_addr` after SimplifyLocals-before-const-prop + // MIR for `expose_provenance` after SimplifyLocals-before-const-prop
fn expose_addr(_1: *const usize) -> () { fn expose_provenance(_1: *const usize) -> () {
debug p => _1; debug p => _1;
let mut _0: (); let mut _0: ();
let _2: usize; let _2: usize;
@ -11,7 +11,7 @@
StorageLive(_2); StorageLive(_2);
StorageLive(_3); StorageLive(_3);
_3 = _1; _3 = _1;
_2 = move _3 as usize (PointerExposeAddress); _2 = move _3 as usize (PointerExposeProvenance);
StorageDead(_3); StorageDead(_3);
StorageDead(_2); StorageDead(_2);
_0 = const (); _0 = const ();

View File

@ -63,8 +63,8 @@ fn t4() -> u32 {
unsafe { X + 1 } unsafe { X + 1 }
} }
// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff // EMIT_MIR simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
fn expose_addr(p: *const usize) { fn expose_provenance(p: *const usize) {
// Used pointer to address cast. Has a side effect of exposing the provenance. // Used pointer to address cast. Has a side effect of exposing the provenance.
p as usize; p as usize;
} }
@ -78,5 +78,5 @@ fn main() {
t2(); t2();
t3(); t3();
t4(); t4();
expose_addr(&0); expose_provenance(&0);
} }

View File

@ -4,7 +4,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
LL | let addr: usize = &x as *const u8 as usize; LL | let addr: usize = &x as *const u8 as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
note: the lint level is defined here note: the lint level is defined here
--> $DIR/lint-strict-provenance-lossy-casts.rs:2:9 --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
| |
@ -21,7 +21,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
LL | let addr_32bit = &x as *const u8 as u32; LL | let addr_32bit = &x as *const u8 as u32;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
help: use `.addr()` to obtain the address of a pointer help: use `.addr()` to obtain the address of a pointer
| |
LL | let addr_32bit = (&x as *const u8).addr() as u32; LL | let addr_32bit = (&x as *const u8).addr() as u32;
@ -35,7 +35,7 @@ LL | let ptr_addr = ptr as usize;
| | | |
| help: use `.addr()` to obtain the address of a pointer: `.addr()` | help: use `.addr()` to obtain the address of a pointer: `.addr()`
| |
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32` error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
--> $DIR/lint-strict-provenance-lossy-casts.rs:16:26 --> $DIR/lint-strict-provenance-lossy-casts.rs:16:26
@ -45,7 +45,7 @@ LL | let ptr_addr_32bit = ptr as u32;
| | | |
| help: use `.addr()` to obtain the address of a pointer: `.addr() as u32` | help: use `.addr()` to obtain the address of a pointer: `.addr() as u32`
| |
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View File

@ -4,7 +4,7 @@
extern "rust-intrinsic" { extern "rust-intrinsic" {
fn simd_cast_ptr<T, U>(x: T) -> U; fn simd_cast_ptr<T, U>(x: T) -> U;
fn simd_expose_addr<T, U>(x: T) -> U; fn simd_expose_provenance<T, U>(x: T) -> U;
fn simd_with_exposed_provenance<T, U>(x: T) -> U; fn simd_with_exposed_provenance<T, U>(x: T) -> U;
} }
@ -22,7 +22,7 @@ fn main() {
// change constness and type // change constness and type
let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs); let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs);
let exposed_addr: V<usize> = simd_expose_addr(const_ptrs); let exposed_addr: V<usize> = simd_expose_provenance(const_ptrs);
let with_exposed_provenance: V<*mut i8> = simd_with_exposed_provenance(exposed_addr); let with_exposed_provenance: V<*mut i8> = simd_with_exposed_provenance(exposed_addr);