From 74ef47e90ca1466ea7f3dd8c3ec3738f05345809 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sun, 17 Mar 2024 00:14:20 -0400 Subject: make CastTarget::size and CastTarget::llvm_type consistent, remove special case that's not present in Clang Making the methods consistent doesn't require much justification. It's required for us to generate correct code. The special case was present near the end of `CastTarget::llvm_type`, and resulted in the final integer component of the ABI type being shrunk to the smallest integer that fits. You can see this in action here (https://godbolt.org/z/Pe73cr91d), where, for a struct with 5 u16 elements, rustc generates `{ i64, i16 }`, while Clang generates `[2 x i64]`. This special case was added a long time ago, when the function was originally written [1]. That commit consolidated logic from many backends, and in some of the code it deleted, sparc64 [2] and powerpc64 [3] had similar special cases. However, looking at Clang today, it doesn't have this special case for sparc64 (https://godbolt.org/z/YaafvYWdf) or powerpc64 (https://godbolt.org/z/5c3YePTje), so this change just removes it. [1]: https://github.com/rust-lang/rust/commit/f0636b61c7f84962a609e831760db9d77f4f5e14#diff-183c4dadf10704bd1f521b71f71d89bf755c9603a93f894d66c03bb1effc6021R231 [2]: https://github.com/rust-lang/rust/commit/f0636b61c7f84962a609e831760db9d77f4f5e14#diff-2d8f87ea6db6d7f0a6fbeb1d5549adc07e93331278d951a1e051a40f92914436L163-L166 [3]: https://github.com/rust-lang/rust/commit/f0636b61c7f84962a609e831760db9d77f4f5e14#diff-88af4a9df9ead503a5c7774a0455d270dea3ba60e9b0ec1ce550b4c53d3bce3bL172-L175 --- compiler/rustc_codegen_llvm/src/abi.rs | 52 ++++++++++++++++------------------ 1 file changed, 24 insertions(+), 28 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index e5f5146fac8..1990634fc51 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -16,13 +16,15 @@ pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use rustc_middle::ty::Ty; use rustc_session::config; pub use rustc_target::abi::call::*; -use rustc_target::abi::{self, HasDataLayout, Int}; +use rustc_target::abi::{self, HasDataLayout, Int, Size}; pub use rustc_target::spec::abi::Abi; use rustc_target::spec::SanitizerSet; use libc::c_uint; use smallvec::SmallVec; +use std::cmp; + pub trait ArgAttributesExt { fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value); fn apply_attrs_to_callsite( @@ -130,42 +132,36 @@ impl LlvmType for Reg { impl LlvmType for CastTarget { fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type { let rest_ll_unit = self.rest.unit.llvm_type(cx); - let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 { - (0, 0) + let rest_count = if self.rest.total == Size::ZERO { + 0 } else { - ( - self.rest.total.bytes() / self.rest.unit.size.bytes(), - self.rest.total.bytes() % self.rest.unit.size.bytes(), - ) + assert_ne!( + self.rest.unit.size, + Size::ZERO, + "total size {:?} cannot be divided into units of zero size", + self.rest.total + ); + if self.rest.total.bytes() % self.rest.unit.size.bytes() != 0 { + assert_eq!(self.rest.unit.kind, RegKind::Integer, "only int regs can be split"); + } + self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes()) }; + // Simplify to a single unit or an array if there's no prefix. + // This produces the same layout, but using a simpler type. if self.prefix.iter().all(|x| x.is_none()) { - // Simplify to a single unit when there is no prefix and size <= unit size - if self.rest.total <= self.rest.unit.size { + if rest_count == 1 { return rest_ll_unit; } - // Simplify to array when all chunks are the same size and type - if rem_bytes == 0 { - return cx.type_array(rest_ll_unit, rest_count); - } - } - - // Create list of fields in the main structure - let mut args: Vec<_> = self - .prefix - .iter() - .flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx))) - .chain((0..rest_count).map(|_| rest_ll_unit)) - .collect(); - - // Append final integer - if rem_bytes != 0 { - // Only integers can be really split further. - assert_eq!(self.rest.unit.kind, RegKind::Integer); - args.push(cx.type_ix(rem_bytes * 8)); + return cx.type_array(rest_ll_unit, rest_count); } + // Generate a struct type with the prefix and the "rest" arguments. + let prefix_args = + self.prefix.iter().flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx))); + let rest_args = (0..rest_count).map(|_| rest_ll_unit); + let args: Vec<_> = prefix_args.chain(rest_args).collect(); cx.type_struct(&args, false) } } -- cgit 1.4.1-3-g733a5 From 8841315d3e9aa02cb54d757cb5cd8131c263a893 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sun, 17 Mar 2024 00:22:35 -0400 Subject: make PassMode::Cast consistently copy between Rust/ABI representation Previously, we did this slightly incorrectly for return values, and didn't do it at all for arguments. --- compiler/rustc_codegen_llvm/src/abi.rs | 68 ++++++++++++----------------- compiler/rustc_codegen_ssa/src/mir/block.rs | 32 ++++++++++++-- 2 files changed, 56 insertions(+), 44 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 1990634fc51..d2828669d43 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -211,47 +211,33 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); } PassMode::Cast { cast, pad_i32: _ } => { - // FIXME(eddyb): Figure out when the simpler Store is safe, clang - // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. - let can_store_through_cast_ptr = false; - if can_store_through_cast_ptr { - bx.store(val, dst.llval, self.layout.align.abi); - } else { - // The actual return type is a struct, but the ABI - // adaptation code has cast it into some scalar type. The - // code that follows is the only reliable way I have - // found to do a transform like i64 -> {i32,i32}. - // Basically we dump the data onto the stack then memcpy it. - // - // Other approaches I tried: - // - Casting rust ret pointer to the foreign type and using Store - // is (a) unsafe if size of foreign type > size of rust type and - // (b) runs afoul of strict aliasing rules, yielding invalid - // assembly under -O (specifically, the store gets removed). - // - Truncating foreign type to correct integral type and then - // bitcasting to the struct type yields invalid cast errors. - - // We instead thus allocate some scratch space... - let scratch_size = cast.size(bx); - let scratch_align = cast.align(bx); - let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align); - bx.lifetime_start(llscratch, scratch_size); - - // ... where we first store the value... - bx.store(val, llscratch, scratch_align); - - // ... and then memcpy it to the intended destination. - bx.memcpy( - dst.llval, - self.layout.align.abi, - llscratch, - scratch_align, - bx.const_usize(self.layout.size.bytes()), - MemFlags::empty(), - ); - - bx.lifetime_end(llscratch, scratch_size); - } + // The ABI mandates that the value is passed as a different struct representation. + // Spill and reload it from the stack to convert from the ABI representation to + // the Rust representation. + let scratch_size = cast.size(bx); + let scratch_align = cast.align(bx); + // Note that the ABI type may be either larger or smaller than the Rust type, + // due to the presence or absence of trailing padding. For example: + // - On some ABIs, the Rust layout { f64, f32, } may omit padding + // when passed by value, making it smaller. + // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes + // when passed by value, making it larger. + let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes()); + // Allocate some scratch space... + let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align); + bx.lifetime_start(llscratch, scratch_size); + // ...store the value... + bx.store(val, llscratch, scratch_align); + // ... and then memcpy it to the intended destination. + bx.memcpy( + dst.llval, + self.layout.align.abi, + llscratch, + scratch_align, + bx.const_usize(copy_bytes), + MemFlags::empty(), + ); + bx.lifetime_end(llscratch, scratch_size); } _ => { OperandRef::from_immediate_or_packed_pair(bx, val, self.layout).val.store(bx, dst); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 9bb2a528265..333c03ce823 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1471,9 +1471,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. - if let PassMode::Cast { cast: ty, .. } = &arg.mode { - let llty = bx.cast_backend_type(ty); - llval = bx.load(llty, llval, align.min(arg.layout.align.abi)); + if let PassMode::Cast { cast, pad_i32: _ } = &arg.mode { + // The ABI mandates that the value is passed as a different struct representation. + // Spill and reload it from the stack to convert from the Rust representation to + // the ABI representation. + let scratch_size = cast.size(bx); + let scratch_align = cast.align(bx); + // Note that the ABI type may be either larger or smaller than the Rust type, + // due to the presence or absence of trailing padding. For example: + // - On some ABIs, the Rust layout { f64, f32, } may omit padding + // when passed by value, making it smaller. + // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes + // when passed by value, making it larger. + let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes()); + // Allocate some scratch space... + let llscratch = bx.alloca(bx.cast_backend_type(cast), scratch_align); + bx.lifetime_start(llscratch, scratch_size); + // ...memcpy the value... + bx.memcpy( + llscratch, + scratch_align, + llval, + align, + bx.const_usize(copy_bytes), + MemFlags::empty(), + ); + // ...and then load it with the ABI type. + let cast_ty = bx.cast_backend_type(cast); + llval = bx.load(cast_ty, llscratch, scratch_align); + bx.lifetime_end(llscratch, scratch_size); } else { // We can't use `PlaceRef::load` here because the argument // may have a type we don't treat as immediate, but the ABI -- cgit 1.4.1-3-g733a5 From 989660c3e6efc1c5eb2e822f68863df7d06cbcb4 Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 3 Apr 2024 15:17:00 +0200 Subject: rename `expose_addr` to `expose_provenance` --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +-- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- .../rustc_codegen_cranelift/src/intrinsics/simd.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- compiler/rustc_const_eval/src/interpret/cast.rs | 6 ++-- .../src/transform/check_consts/check.rs | 2 +- .../rustc_const_eval/src/transform/validate.rs | 2 +- compiler/rustc_hir_analysis/src/check/intrinsic.rs | 2 +- compiler/rustc_hir_typeck/messages.ftl | 2 +- compiler/rustc_lint_defs/src/builtin.rs | 6 ++-- compiler/rustc_middle/src/mir/statement.rs | 2 +- compiler/rustc_middle/src/mir/syntax.rs | 4 +-- compiler/rustc_middle/src/ty/cast.rs | 2 +- compiler/rustc_mir_transform/src/promote_consts.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 2 +- compiler/rustc_smir/src/rustc_smir/convert/mir.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- compiler/stable_mir/src/mir/body.rs | 1 + library/core/src/fmt/mod.rs | 4 +-- library/core/src/intrinsics/simd.rs | 6 ++++ library/core/src/ptr/const_ptr.rs | 10 +++--- library/core/src/ptr/mod.rs | 14 ++++---- library/core/src/ptr/mut_ptr.rs | 11 +++--- .../crates/core_simd/src/simd/ptr/const_ptr.rs | 10 +++--- .../crates/core_simd/src/simd/ptr/mut_ptr.rs | 10 +++--- .../crates/core_simd/tests/pointers.rs | 6 ++-- library/std/src/sys/pal/hermit/thread.rs | 2 +- library/std/src/sys/pal/itron/thread.rs | 2 +- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/miri/src/alloc_addresses/mod.rs | 4 +-- src/tools/miri/src/shims/intrinsics/simd.rs | 6 ++-- .../miri/tests/fail/provenance/ptr_invalid.rs | 2 +- .../tests/fail/stacked_borrows/exposed_only_ro.rs | 2 +- src/tools/miri/tests/pass/portable-simd-ptrs.rs | 2 +- src/tools/miri/tests/pass/ptr_int_from_exposed.rs | 10 +++--- .../miri/tests/pass/stacked-borrows/int-to-ptr.rs | 4 +-- .../pass/stacked-borrows/unknown-bottom-gc.rs | 2 +- ...ointer_expose_address.main.GVN.panic-abort.diff | 41 ---------------------- ...inter_expose_address.main.GVN.panic-unwind.diff | 41 ---------------------- tests/mir-opt/const_prop/pointer_expose_address.rs | 17 --------- ...ter_expose_provenance.main.GVN.panic-abort.diff | 41 ++++++++++++++++++++++ ...er_expose_provenance.main.GVN.panic-unwind.diff | 41 ++++++++++++++++++++++ .../const_prop/pointer_expose_provenance.rs | 17 +++++++++ .../mir-opt/const_prop/reify_fn_ptr.main.GVN.diff | 2 +- tests/mir-opt/const_prop/reify_fn_ptr.rs | 2 +- ...ointer_to_int.DeadStoreElimination-initial.diff | 4 +-- .../dead-store-elimination/provenance_soundness.rs | 4 +-- ...pose_addr.SimplifyLocals-before-const-prop.diff | 21 ----------- ...rovenance.SimplifyLocals-before-const-prop.diff | 21 +++++++++++ tests/mir-opt/simplify_locals.rs | 6 ++-- .../lint/lint-strict-provenance-lossy-casts.stderr | 8 ++--- tests/ui/simd/intrinsic/ptr-cast.rs | 4 +-- 53 files changed, 217 insertions(+), 211 deletions(-) delete mode 100644 tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff delete mode 100644 tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff delete mode 100644 tests/mir-opt/const_prop/pointer_expose_address.rs create mode 100644 tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff create mode 100644 tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff create mode 100644 tests/mir-opt/const_prop/pointer_expose_provenance.rs delete mode 100644 tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff create mode 100644 tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6405364c30c..71b54a761a2 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2261,7 +2261,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerExposeAddress => { + CastKind::PointerExposeProvenance => { let ty_from = op.ty(body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); @@ -2271,7 +2271,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!( self, rvalue, - "Invalid PointerExposeAddress cast {:?} -> {:?}", + "Invalid PointerExposeProvenance cast {:?} -> {:?}", ty_from, ty ) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 249c16898ce..0aa2bae8f78 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -649,7 +649,7 @@ fn codegen_stmt<'tcx>( | CastKind::IntToFloat | CastKind::FnPtrToPtr | CastKind::PtrToPtr - | CastKind::PointerExposeAddress + | CastKind::PointerExposeProvenance | CastKind::PointerWithExposedProvenance, ref operand, to_ty, diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 783ad5d1dd1..67f9d831062 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -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); ret.write_cvalue_transmute(fx, arg); } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index e4ec7974e90..dc52dd156b7 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -2111,7 +2111,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( 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); require!( in_len == out_len, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 6f7b98a262d..4d746c89f1f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -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 val = match *kind { - mir::CastKind::PointerExposeAddress => { + mir::CastKind::PointerExposeProvenance => { assert!(bx.cx().is_backend_immediate(cast)); let llptr = operand.immediate(); let llcast_ty = bx.cx().immediate_backend_type(cast); diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index e0d45f1fe11..9447d18fe8c 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -34,9 +34,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.unsize_into(src, cast_layout, dest)?; } - CastKind::PointerExposeAddress => { + CastKind::PointerExposeProvenance => { 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)?; } @@ -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, src: &ImmTy<'tcx, M::Provenance>, cast_to: TyAndLayout<'tcx>, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index b6dcc334147..543996c86ba 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -544,7 +544,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Unsizing is implemented for CTFE. } - Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { + Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { self.check_op(ops::RawPtrToIntCast); } Rvalue::Cast(CastKind::PointerWithExposedProvenance, _, _) => { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index e1e98ebc1e9..a499e4b980f 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -1077,7 +1077,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } // FIXME: Add Checks for these CastKind::PointerWithExposedProvenance - | CastKind::PointerExposeAddress + | CastKind::PointerExposeProvenance | CastKind::PointerCoercion(_) => {} CastKind::IntToInt | CastKind::IntToFloat => { let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool(); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 00a0fca4907..cea6f3c1dba 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -627,7 +627,7 @@ pub fn check_intrinsic_type( sym::simd_cast | sym::simd_as | 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_bitmask => (2, 0, vec![param(0)], param(1)), sym::simd_select | sym::simd_select_bitmask => { diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index fbdc3d1adb8..1d51101c940 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -91,7 +91,7 @@ hir_typeck_lossy_provenance_int2ptr = hir_typeck_lossy_provenance_ptr2int = 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 - .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 = cannot call a method on a raw pointer with an unknown pointee type diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7e9d35ca6c1..30522628f46 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2797,17 +2797,17 @@ declare_lint! { /// 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 /// "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. /// /// 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 /// about the semantics. /// /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 /// [`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, Allow, "a lossy pointer to integer cast is used", diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 947764307e4..069c8019cb2 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -409,7 +409,7 @@ impl<'tcx> Rvalue<'tcx> { // Pointer to int casts may be side-effects due to exposing the provenance. // While the model is undecided, we should be conservative. See // - Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false, + Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => false, Rvalue::Use(_) | Rvalue::CopyForDeref(_) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 1f6165babdf..7ce48036a68 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1309,8 +1309,8 @@ pub enum Rvalue<'tcx> { pub enum CastKind { /// An exposing pointer to address cast. A cast between a pointer and an integer type, or /// between a function pointer and an integer type. - /// See the docs on `expose_addr` for more details. - PointerExposeAddress, + /// See the docs on `expose_provenance` for more details. + PointerExposeProvenance, /// An address-to-pointer cast that picks up an exposed provenance. /// See the docs on `with_exposed_provenance` for more details. PointerWithExposedProvenance, diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 9bdc679d4e5..c9fd20bc112 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -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_kind = match (from, cast) { (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::DynStar)) => mir::CastKind::DynStar, diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index d64cb9b12b2..a9d4b860b7a 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -434,7 +434,7 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::ThreadLocalRef(_) => return Err(Unpromotable), // 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 // at pointer type. diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index b60ee7649b2..93bad882625 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -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 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( CastKind::FnPtrToPtr, Operand::Move(Place::from(Local::new(1))), diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 9d91032c1d2..c9f66612590 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -267,7 +267,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { use rustc_middle::mir::CastKind::*; match self { - PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress, + PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), DynStar => stable_mir::mir::CastKind::DynStar, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b1d4a63812f..a13c9c9b278 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1659,7 +1659,7 @@ symbols! { simd_cttz, simd_div, simd_eq, - simd_expose_addr, + simd_expose_provenance, simd_extract, simd_fabs, simd_fcos, diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 0d866f27dad..8f77a19fc0e 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -971,6 +971,7 @@ pub enum PointerCoercion { #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum CastKind { + // FIXME(smir-rename): rename this to PointerExposeProvenance PointerExposeAddress, PointerWithExposedProvenance, PointerCoercion(PointerCoercion), diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index e880d5758ec..287f6c23c89 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2438,8 +2438,8 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - // Cast is needed here because `.expose_addr()` requires `T: Sized`. - pointer_fmt_inner((*self as *const ()).expose_addr(), f) + // Cast is needed here because `.expose_provenance()` requires `T: Sized`. + pointer_fmt_inner((*self as *const ()).expose_provenance(), f) } } diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 614b4b589d3..eeff4ec609a 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -540,6 +540,10 @@ extern "rust-intrinsic" { /// `T` must be a vector of pointers. /// /// `U` must be a vector of `usize` with the same length as `T`. + #[cfg(not(bootstrap))] + #[rustc_nounwind] + pub fn simd_expose_provenance(ptr: T) -> U; + #[cfg(bootstrap)] #[rustc_nounwind] pub fn simd_expose_addr(ptr: T) -> U; @@ -660,5 +664,7 @@ extern "rust-intrinsic" { pub fn simd_flog(a: T) -> T; } +#[cfg(bootstrap)] +pub use simd_expose_addr as simd_expose_provenance; #[cfg(bootstrap)] pub use simd_from_exposed_addr as simd_with_exposed_provenance; diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index e5713ee89df..01db050e666 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -136,7 +136,7 @@ impl *const T { #[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[deprecated( 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" )] #[inline(always)] @@ -187,7 +187,7 @@ impl *const T { /// /// 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 - /// 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 /// that check for compliance with the Rust memory model. /// @@ -210,8 +210,8 @@ impl *const T { unsafe { mem::transmute(self.cast::<()>()) } } - /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future - /// use in [`with_exposed_provenance`][]. + /// Exposes the "provenance" part of the pointer for future use in + /// [`with_exposed_provenance`][] and returns the "address" portion. /// /// This is equivalent to `self as usize`, which semantically discards *provenance* and /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit @@ -238,7 +238,7 @@ impl *const T { #[must_use] #[inline(always)] #[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. self.cast::<()>() as usize } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 28df2b04c88..f12ab3d50cd 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -340,8 +340,8 @@ //! 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]. //! -//! Exposed Provenance is provided by the [`expose_addr`] and [`with_exposed_provenance`] methods, which -//! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like +//! Exposed Provenance is provided by the [`expose_provenance`] and [`with_exposed_provenance`] methods, +//! 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' //! 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`] @@ -355,9 +355,9 @@ //! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will //! 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 -//! 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. //! 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 @@ -374,7 +374,7 @@ //! [`map_addr`]: pointer::map_addr //! [`addr`]: pointer::addr //! [`ptr::dangling`]: core::ptr::dangling -//! [`expose_addr`]: pointer::expose_addr +//! [`expose_provenance`]: pointer::expose_provenance //! [`with_exposed_provenance`]: with_exposed_provenance //! [Miri]: https://github.com/rust-lang/miri //! [CHERI]: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/ @@ -663,7 +663,7 @@ pub const fn dangling_mut() -> *mut T { /// /// 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 -/// [`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 /// 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. @@ -711,7 +711,7 @@ where /// /// 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 -/// [`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 /// 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 diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 042658fa35f..41e5ba67458 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -142,7 +142,7 @@ impl *mut T { #[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[deprecated( 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" )] #[inline(always)] @@ -194,7 +194,7 @@ impl *mut T { /// /// 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 - /// 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 /// that check for compliance with the Rust memory model. /// @@ -217,8 +217,8 @@ impl *mut T { unsafe { mem::transmute(self.cast::<()>()) } } - /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future - /// use in [`with_exposed_provenance`][]. + /// Exposes the "provenance" part of the pointer for future use in + /// [`with_exposed_provenance`][] and returns the "address" portion. /// /// This is equivalent to `self as usize`, which semantically discards *provenance* and /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit @@ -242,10 +242,9 @@ impl *mut T { /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance]. /// /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut - #[must_use] #[inline(always)] #[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. self.cast::<()>() as usize } diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs index 4d2fe999ca6..0f1719206c9 100644 --- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs +++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs @@ -50,9 +50,9 @@ pub trait SimdConstPtr: Copy + Sealed { /// Equivalent to calling [`pointer::with_addr`] on each element. fn with_addr(self, addr: Self::Usize) -> Self; - /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use - /// in [`Self::with_exposed_provenance`]. - fn expose_addr(self) -> Self::Usize; + /// Exposes the "provenance" part of the pointer for future use in + /// [`Self::with_exposed_provenance`] and returns the "address" portion. + fn expose_provenance(self) -> Self::Usize; /// Convert an address back to a pointer, picking up a previously "exposed" provenance. /// @@ -131,9 +131,9 @@ where } #[inline] - fn expose_addr(self) -> Self::Usize { + fn expose_provenance(self) -> Self::Usize { // Safety: `self` is a pointer vector - unsafe { core::intrinsics::simd::simd_expose_addr(self) } + unsafe { core::intrinsics::simd::simd_expose_provenance(self) } } #[inline] diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs index b3437b9c499..7ba996d149c 100644 --- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs +++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs @@ -47,9 +47,9 @@ pub trait SimdMutPtr: Copy + Sealed { /// Equivalent to calling [`pointer::with_addr`] on each element. fn with_addr(self, addr: Self::Usize) -> Self; - /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use - /// in [`Self::with_exposed_provenance`]. - fn expose_addr(self) -> Self::Usize; + /// Exposes the "provenance" part of the pointer for future use in + /// [`Self::with_exposed_provenance`] and returns the "address" portion. + fn expose_provenance(self) -> Self::Usize; /// Convert an address back to a pointer, picking up a previously "exposed" provenance. /// @@ -128,9 +128,9 @@ where } #[inline] - fn expose_addr(self) -> Self::Usize { + fn expose_provenance(self) -> Self::Usize { // Safety: `self` is a pointer vector - unsafe { core::intrinsics::simd::simd_expose_addr(self) } + unsafe { core::intrinsics::simd::simd_expose_provenance(self) } } #[inline] diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs index 5984fdae2f9..90bfc5d5fd6 100644 --- a/library/portable-simd/crates/core_simd/tests/pointers.rs +++ b/library/portable-simd/crates/core_simd/tests/pointers.rs @@ -32,10 +32,10 @@ macro_rules! common_tests { ); } - fn expose_addr() { + fn expose_provenance() { test_helpers::test_unary_elementwise( - &Simd::<*$constness u32, LANES>::expose_addr, - &<*$constness u32>::expose_addr, + &Simd::<*$constness u32, LANES>::expose_provenance, + &<*$constness u32>::expose_provenance, &|_| true, ); } diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index 62c76a74cd4..40f88e33d4a 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -29,7 +29,7 @@ impl Thread { let p = Box::into_raw(Box::new(p)); let tid = abi::spawn2( thread_start, - p.expose_addr(), + p.expose_provenance(), abi::Priority::into(abi::NORMAL_PRIO), stack, core_id, diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs index 1c66bd79ce4..047513a6792 100644 --- a/library/std/src/sys/pal/itron/thread.rs +++ b/library/std/src/sys/pal/itron/thread.rs @@ -181,7 +181,7 @@ impl Thread { abi::acre_tsk(&abi::T_CTSK { // Activate this task immediately 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 task: Some(trampoline), // Inherit the calling task's base priority diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 12b08005997..325c9bee057 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -149,7 +149,7 @@ fn check_rvalue<'tcx>( 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())) }, Rvalue::Cast(CastKind::DynStar, _, _) => { diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 6b8e1510a6b..fec39ec2b8e 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -18,8 +18,8 @@ use reuse_pool::ReusePool; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ProvenanceMode { - /// We support `expose_addr`/`with_exposed_provenance` via "wildcard" provenance. - /// However, we want on `with_exposed_provenance` to alert the user of the precision loss. + /// We support `expose_provenance`/`with_exposed_provenance` via "wildcard" provenance. + /// However, we warn on `with_exposed_provenance` to alert the user of the precision loss. Default, /// Like `Default`, but without the warning. Permissive, diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index 9d268f09edb..a2fc4f0f761 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -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)?; 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, op_len) = this.operand_to_simd(op)?; 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 safe_cast = intrinsic_name == "as"; 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"; 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)?, // Ptr/Int casts (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 => this.pointer_with_exposed_provenance_cast(&op, dest.layout)?, // Error otherwise diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs index 730859684a0..512473cd894 100644 --- a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs +++ b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs @@ -4,6 +4,6 @@ fn main() { let x = 42; let xptr = &x as *const i32; - let xptr_invalid = std::ptr::without_provenance::(xptr.expose_addr()); + let xptr_invalid = std::ptr::without_provenance::(xptr.expose_provenance()); let _val = unsafe { *xptr_invalid }; //~ ERROR: is a dangling pointer } diff --git a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs index aa05649d550..608ab718919 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs @@ -6,7 +6,7 @@ fn main() { let mut x = 0; 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::(addr); unsafe { *ptr = 0 }; //~ ERROR: /write access using .* no exposed tags have suitable permission in the borrow stack/ } diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/portable-simd-ptrs.rs index 3b2d221bd8e..096ec78da1a 100644 --- a/src/tools/miri/tests/pass/portable-simd-ptrs.rs +++ b/src/tools/miri/tests/pass/portable-simd-ptrs.rs @@ -7,6 +7,6 @@ use std::simd::prelude::*; fn main() { // Pointer casts 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); } diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs index 8555de986f0..5690d7865bb 100644 --- a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs +++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs @@ -10,7 +10,7 @@ fn ptr_roundtrip_out_of_bounds() { let x: i32 = 3; 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::(x_usize).wrapping_offset(-128); assert_eq!(unsafe { *ptr }, 3); @@ -24,8 +24,8 @@ fn ptr_roundtrip_confusion() { let x_ptr = &x as *const i32; let y_ptr = &y as *const i32; - let x_usize = x_ptr.expose_addr(); - let y_usize = y_ptr.expose_addr(); + let x_usize = x_ptr.expose_provenance(); + let y_usize = y_ptr.expose_provenance(); let ptr = ptr::with_exposed_provenance::(y_usize); let ptr = ptr.with_addr(x_usize); @@ -37,7 +37,7 @@ fn ptr_roundtrip_imperfect() { let x: u8 = 3; 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::(x_usize).wrapping_offset(-128); assert_eq!(unsafe { *ptr }, 3); @@ -48,7 +48,7 @@ fn ptr_roundtrip_null() { let x = &42; 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 null = x_null_ptr.expose_addr(); + let null = x_null_ptr.expose_provenance(); assert_eq!(null, 0); let x_null_ptr_copy = ptr::with_exposed_provenance::(null); // just a roundtrip, so has provenance of x (angelically) diff --git a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs index 5622bf18654..c89d79b42e3 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs @@ -17,7 +17,7 @@ fn example(variant: bool) { unsafe { fn not_so_innocent(x: &mut u32) -> usize { let x_raw4 = x as *mut u32; - x_raw4.expose_addr() + x_raw4.expose_provenance() } let mut c = 42u32; @@ -26,7 +26,7 @@ fn example(variant: bool) { // stack: [..., Unique(1)] 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)] let x_unique3 = &mut *x_raw2; diff --git a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs index 6e177a6e4ab..55356814a1a 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs @@ -9,7 +9,7 @@ fn main() { // Expose the allocation and use the exposed pointer, creating an unknown bottom unsafe { - let p: *mut u8 = ptr::with_exposed_provenance::(ptr.expose_addr()) as *mut u8; + let p: *mut u8 = ptr::with_exposed_provenance::(ptr.expose_provenance()) as *mut u8; *p = 1; } diff --git a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff deleted file mode 100644 index 596eb1a9966..00000000000 --- a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff +++ /dev/null @@ -1,41 +0,0 @@ -- // MIR for `main` before GVN -+ // MIR for `main` after GVN - - fn main() -> () { - let mut _0: (); - let _1: usize; - let mut _2: *const i32; - let _3: &i32; - let _4: (); - let mut _5: usize; - scope 1 { - debug x => _1; - } - - bb0: { -- StorageLive(_1); -+ nop; - StorageLive(_2); - StorageLive(_3); - _3 = const main::FOO; - _2 = &raw const (*_3); - _1 = move _2 as usize (PointerExposeAddress); - StorageDead(_2); - StorageDead(_3); - StorageLive(_4); - StorageLive(_5); - _5 = _1; -- _4 = read(move _5) -> [return: bb1, unwind unreachable]; -+ _4 = read(_1) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_5); - StorageDead(_4); - _0 = const (); -- StorageDead(_1); -+ nop; - return; - } - } - diff --git a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff deleted file mode 100644 index 995f281ecf5..00000000000 --- a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff +++ /dev/null @@ -1,41 +0,0 @@ -- // MIR for `main` before GVN -+ // MIR for `main` after GVN - - fn main() -> () { - let mut _0: (); - let _1: usize; - let mut _2: *const i32; - let _3: &i32; - let _4: (); - let mut _5: usize; - scope 1 { - debug x => _1; - } - - bb0: { -- StorageLive(_1); -+ nop; - StorageLive(_2); - StorageLive(_3); - _3 = const main::FOO; - _2 = &raw const (*_3); - _1 = move _2 as usize (PointerExposeAddress); - StorageDead(_2); - StorageDead(_3); - StorageLive(_4); - StorageLive(_5); - _5 = _1; -- _4 = read(move _5) -> [return: bb1, unwind continue]; -+ _4 = read(_1) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_5); - StorageDead(_4); - _0 = const (); -- StorageDead(_1); -+ nop; - return; - } - } - diff --git a/tests/mir-opt/const_prop/pointer_expose_address.rs b/tests/mir-opt/const_prop/pointer_expose_address.rs deleted file mode 100644 index a6b4f8857c3..00000000000 --- a/tests/mir-opt/const_prop/pointer_expose_address.rs +++ /dev/null @@ -1,17 +0,0 @@ -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//@ unit-test: GVN - -#[inline(never)] -fn read(_: usize) { } - -// EMIT_MIR pointer_expose_address.main.GVN.diff -fn main() { - // CHECK-LABEL: fn main( - // CHECK: [[ptr:_.*]] = const main::FOO; - // CHECK: [[ref:_.*]] = &raw const (*[[ptr]]); - // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeAddress); - // CHECK: = read([[x]]) - const FOO: &i32 = &1; - let x = FOO as *const i32 as usize; - read(x); -} diff --git a/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff new file mode 100644 index 00000000000..79a95b618d1 --- /dev/null +++ b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff @@ -0,0 +1,41 @@ +- // MIR for `main` before GVN ++ // MIR for `main` after GVN + + fn main() -> () { + let mut _0: (); + let _1: usize; + let mut _2: *const i32; + let _3: &i32; + let _4: (); + let mut _5: usize; + scope 1 { + debug x => _1; + } + + bb0: { +- StorageLive(_1); ++ nop; + StorageLive(_2); + StorageLive(_3); + _3 = const main::FOO; + _2 = &raw const (*_3); + _1 = move _2 as usize (PointerExposeProvenance); + StorageDead(_2); + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); + _5 = _1; +- _4 = read(move _5) -> [return: bb1, unwind unreachable]; ++ _4 = read(_1) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_5); + StorageDead(_4); + _0 = const (); +- StorageDead(_1); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff new file mode 100644 index 00000000000..9d1bcd92fef --- /dev/null +++ b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff @@ -0,0 +1,41 @@ +- // MIR for `main` before GVN ++ // MIR for `main` after GVN + + fn main() -> () { + let mut _0: (); + let _1: usize; + let mut _2: *const i32; + let _3: &i32; + let _4: (); + let mut _5: usize; + scope 1 { + debug x => _1; + } + + bb0: { +- StorageLive(_1); ++ nop; + StorageLive(_2); + StorageLive(_3); + _3 = const main::FOO; + _2 = &raw const (*_3); + _1 = move _2 as usize (PointerExposeProvenance); + StorageDead(_2); + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); + _5 = _1; +- _4 = read(move _5) -> [return: bb1, unwind continue]; ++ _4 = read(_1) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_5); + StorageDead(_4); + _0 = const (); +- StorageDead(_1); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/const_prop/pointer_expose_provenance.rs b/tests/mir-opt/const_prop/pointer_expose_provenance.rs new file mode 100644 index 00000000000..840a4d65f3d --- /dev/null +++ b/tests/mir-opt/const_prop/pointer_expose_provenance.rs @@ -0,0 +1,17 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ unit-test: GVN + +#[inline(never)] +fn read(_: usize) { } + +// EMIT_MIR pointer_expose_provenance.main.GVN.diff +fn main() { + // CHECK-LABEL: fn main( + // CHECK: [[ptr:_.*]] = const main::FOO; + // CHECK: [[ref:_.*]] = &raw const (*[[ptr]]); + // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeProvenance); + // CHECK: = read([[x]]) + const FOO: &i32 = &1; + let x = FOO as *const i32 as usize; + read(x); +} diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff index 2f76e74a3f8..e5786bcf701 100644 --- a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff +++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff @@ -14,7 +14,7 @@ StorageLive(_2); StorageLive(_3); _3 = main as fn() (PointerCoercion(ReifyFnPointer)); - _2 = move _3 as usize (PointerExposeAddress); + _2 = move _3 as usize (PointerExposeProvenance); StorageDead(_3); _1 = move _2 as *const fn() (PointerWithExposedProvenance); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs index 4e897d22768..55dca24f3d2 100644 --- a/tests/mir-opt/const_prop/reify_fn_ptr.rs +++ b/tests/mir-opt/const_prop/reify_fn_ptr.rs @@ -4,7 +4,7 @@ fn main() { // CHECK-LABEL: fn main( // 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); let _ = main as usize as *const fn(); } diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff index 9b0dc6b6af6..56d5c24ae1d 100644 --- a/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff +++ b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff @@ -19,12 +19,12 @@ StorageLive(_2); StorageLive(_3); _3 = _1; - _2 = move _3 as usize (PointerExposeAddress); + _2 = move _3 as usize (PointerExposeProvenance); StorageDead(_3); StorageLive(_4); StorageLive(_5); _5 = _1; - _4 = move _5 as isize (PointerExposeAddress); + _4 = move _5 as isize (PointerExposeProvenance); StorageDead(_5); _0 = const (); StorageDead(_4); diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs index 96268cd957e..20517a00489 100644 --- a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs +++ b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs @@ -5,8 +5,8 @@ // EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff fn pointer_to_int(p: *mut i32) { // CHECK-LABEL: fn pointer_to_int( - // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeAddress); - // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeAddress); + // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeProvenance); + // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeProvenance); let _x = p as usize; let _y = p as isize; } diff --git a/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff deleted file mode 100644 index 9ebee3df62c..00000000000 --- a/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff +++ /dev/null @@ -1,21 +0,0 @@ -- // MIR for `expose_addr` before SimplifyLocals-before-const-prop -+ // MIR for `expose_addr` after SimplifyLocals-before-const-prop - - fn expose_addr(_1: *const usize) -> () { - debug p => _1; - let mut _0: (); - let _2: usize; - let mut _3: *const usize; - - bb0: { - StorageLive(_2); - StorageLive(_3); - _3 = _1; - _2 = move _3 as usize (PointerExposeAddress); - StorageDead(_3); - StorageDead(_2); - _0 = const (); - return; - } - } - diff --git a/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..cc5c642407e --- /dev/null +++ b/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,21 @@ +- // MIR for `expose_provenance` before SimplifyLocals-before-const-prop ++ // MIR for `expose_provenance` after SimplifyLocals-before-const-prop + + fn expose_provenance(_1: *const usize) -> () { + debug p => _1; + let mut _0: (); + let _2: usize; + let mut _3: *const usize; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + _2 = move _3 as usize (PointerExposeProvenance); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/simplify_locals.rs b/tests/mir-opt/simplify_locals.rs index f95e9185f44..756679e77e3 100644 --- a/tests/mir-opt/simplify_locals.rs +++ b/tests/mir-opt/simplify_locals.rs @@ -63,8 +63,8 @@ fn t4() -> u32 { unsafe { X + 1 } } -// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff -fn expose_addr(p: *const usize) { +// EMIT_MIR simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff +fn expose_provenance(p: *const usize) { // Used pointer to address cast. Has a side effect of exposing the provenance. p as usize; } @@ -78,5 +78,5 @@ fn main() { t2(); t3(); t4(); - expose_addr(&0); + expose_provenance(&0); } diff --git a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr index aa151fe2d21..390028b349e 100644 --- a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr +++ b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr @@ -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; | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^ | - = 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 | 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: 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` --> $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: 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 diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs index 62820346241..0490734b48a 100644 --- a/tests/ui/simd/intrinsic/ptr-cast.rs +++ b/tests/ui/simd/intrinsic/ptr-cast.rs @@ -4,7 +4,7 @@ extern "rust-intrinsic" { fn simd_cast_ptr(x: T) -> U; - fn simd_expose_addr(x: T) -> U; + fn simd_expose_provenance(x: T) -> U; fn simd_with_exposed_provenance(x: T) -> U; } @@ -22,7 +22,7 @@ fn main() { // change constness and type let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs); - let exposed_addr: V = simd_expose_addr(const_ptrs); + let exposed_addr: V = simd_expose_provenance(const_ptrs); let with_exposed_provenance: V<*mut i8> = simd_with_exposed_provenance(exposed_addr); -- cgit 1.4.1-3-g733a5