mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
rename expose_addr
to expose_provenance
This commit is contained in:
parent
99c42d2340
commit
989660c3e6
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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>,
|
||||||
|
@ -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, _, _) => {
|
||||||
|
@ -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();
|
||||||
|
@ -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 => {
|
||||||
|
@ -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
|
||||||
|
@ -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",
|
||||||
|
@ -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(_)
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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))),
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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),
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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, _, _) => {
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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/
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
@ -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);
|
@ -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;
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 ();
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user