mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #79684 - usbalbin:const_copy, r=oli-obk
Make copy[_nonoverlapping] const Constifies * `intrinsics::copy` and `intrinsics::copy_nonoverlapping` * `ptr::read` and `ptr::read_unaligned` * `*const T::read` and `*const T::read_unaligned` * `*mut T::read` and `*mut T::read_unaligned` * `MaybeUninit::assume_init_read`
This commit is contained in:
commit
bbcaed03bf
@ -322,6 +322,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
let result = Scalar::from_uint(truncated_bits, layout.size);
|
let result = Scalar::from_uint(truncated_bits, layout.size);
|
||||||
self.write_scalar(result, dest)?;
|
self.write_scalar(result, dest)?;
|
||||||
}
|
}
|
||||||
|
sym::copy | sym::copy_nonoverlapping => {
|
||||||
|
let elem_ty = instance.substs.type_at(0);
|
||||||
|
let elem_layout = self.layout_of(elem_ty)?;
|
||||||
|
let count = self.read_scalar(args[2])?.to_machine_usize(self)?;
|
||||||
|
let elem_align = elem_layout.align.abi;
|
||||||
|
|
||||||
|
let size = elem_layout.size.checked_mul(count, self).ok_or_else(|| {
|
||||||
|
err_ub_format!("overflow computing total size of `{}`", intrinsic_name)
|
||||||
|
})?;
|
||||||
|
let src = self.read_scalar(args[0])?.check_init()?;
|
||||||
|
let src = self.memory.check_ptr_access(src, size, elem_align)?;
|
||||||
|
let dest = self.read_scalar(args[1])?.check_init()?;
|
||||||
|
let dest = self.memory.check_ptr_access(dest, size, elem_align)?;
|
||||||
|
|
||||||
|
if let (Some(src), Some(dest)) = (src, dest) {
|
||||||
|
self.memory.copy(
|
||||||
|
src,
|
||||||
|
dest,
|
||||||
|
size,
|
||||||
|
intrinsic_name == sym::copy_nonoverlapping,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
sym::offset => {
|
sym::offset => {
|
||||||
let ptr = self.read_scalar(args[0])?.check_init()?;
|
let ptr = self.read_scalar(args[0])?.check_init()?;
|
||||||
let offset_count = self.read_scalar(args[1])?.to_machine_isize(self)?;
|
let offset_count = self.read_scalar(args[1])?.to_machine_isize(self)?;
|
||||||
|
@ -1846,20 +1846,22 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
|
|||||||
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
|
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
|
||||||
#[doc(alias = "memcpy")]
|
#[doc(alias = "memcpy")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(debug_assertions)
|
// FIXME: Perform these checks only at run time
|
||||||
|
/*if cfg!(debug_assertions)
|
||||||
&& !(is_aligned_and_not_null(src)
|
&& !(is_aligned_and_not_null(src)
|
||||||
&& is_aligned_and_not_null(dst)
|
&& is_aligned_and_not_null(dst)
|
||||||
&& is_nonoverlapping(src, dst, count))
|
&& is_nonoverlapping(src, dst, count))
|
||||||
{
|
{
|
||||||
// Not panicking to keep codegen impact smaller.
|
// Not panicking to keep codegen impact smaller.
|
||||||
abort();
|
abort();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// SAFETY: the safety contract for `copy_nonoverlapping` must be
|
// SAFETY: the safety contract for `copy_nonoverlapping` must be
|
||||||
// upheld by the caller.
|
// upheld by the caller.
|
||||||
@ -1928,16 +1930,19 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
|||||||
/// ```
|
/// ```
|
||||||
#[doc(alias = "memmove")]
|
#[doc(alias = "memmove")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")]
|
||||||
fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
|
// FIXME: Perform these checks only at run time
|
||||||
|
/*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
|
||||||
// Not panicking to keep codegen impact smaller.
|
// Not panicking to keep codegen impact smaller.
|
||||||
abort();
|
abort();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// SAFETY: the safety contract for `copy` must be upheld by the caller.
|
// SAFETY: the safety contract for `copy` must be upheld by the caller.
|
||||||
unsafe { copy(src, dst, count) }
|
unsafe { copy(src, dst, count) }
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
#![feature(const_assert_type)]
|
#![feature(const_assert_type)]
|
||||||
#![feature(const_discriminant)]
|
#![feature(const_discriminant)]
|
||||||
#![feature(const_cell_into_inner)]
|
#![feature(const_cell_into_inner)]
|
||||||
|
#![feature(const_intrinsic_copy)]
|
||||||
#![feature(const_checked_int_methods)]
|
#![feature(const_checked_int_methods)]
|
||||||
#![feature(const_euclidean_int_methods)]
|
#![feature(const_euclidean_int_methods)]
|
||||||
#![feature(const_float_classify)]
|
#![feature(const_float_classify)]
|
||||||
@ -93,6 +94,7 @@
|
|||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
#![feature(const_ptr_offset)]
|
#![feature(const_ptr_offset)]
|
||||||
#![feature(const_ptr_offset_from)]
|
#![feature(const_ptr_offset_from)]
|
||||||
|
#![feature(const_ptr_read)]
|
||||||
#![feature(const_raw_ptr_comparison)]
|
#![feature(const_raw_ptr_comparison)]
|
||||||
#![feature(const_raw_ptr_deref)]
|
#![feature(const_raw_ptr_deref)]
|
||||||
#![feature(const_slice_from_raw_parts)]
|
#![feature(const_slice_from_raw_parts)]
|
||||||
|
@ -575,8 +575,9 @@ impl<T> MaybeUninit<T> {
|
|||||||
/// // they both get dropped!
|
/// // they both get dropped!
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
|
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
|
||||||
|
#[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn assume_init_read(&self) -> T {
|
pub const unsafe fn assume_init_read(&self) -> T {
|
||||||
// SAFETY: the caller must guarantee that `self` is initialized.
|
// SAFETY: the caller must guarantee that `self` is initialized.
|
||||||
// Reading from `self.as_ptr()` is safe since `self` should be initialized.
|
// Reading from `self.as_ptr()` is safe since `self` should be initialized.
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -745,8 +745,9 @@ impl<T: ?Sized> *const T {
|
|||||||
///
|
///
|
||||||
/// [`ptr::read`]: crate::ptr::read()
|
/// [`ptr::read`]: crate::ptr::read()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read(self) -> T
|
pub const unsafe fn read(self) -> T
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
{
|
{
|
||||||
@ -783,8 +784,9 @@ impl<T: ?Sized> *const T {
|
|||||||
///
|
///
|
||||||
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
|
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read_unaligned(self) -> T
|
pub const unsafe fn read_unaligned(self) -> T
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
{
|
{
|
||||||
|
@ -685,7 +685,8 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
|
|||||||
/// [valid]: self#safety
|
/// [valid]: self#safety
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub unsafe fn read<T>(src: *const T) -> T {
|
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||||
|
pub const unsafe fn read<T>(src: *const T) -> T {
|
||||||
// `copy_nonoverlapping` takes care of debug_assert.
|
// `copy_nonoverlapping` takes care of debug_assert.
|
||||||
let mut tmp = MaybeUninit::<T>::uninit();
|
let mut tmp = MaybeUninit::<T>::uninit();
|
||||||
// SAFETY: the caller must guarantee that `src` is valid for reads.
|
// SAFETY: the caller must guarantee that `src` is valid for reads.
|
||||||
@ -784,7 +785,8 @@ pub unsafe fn read<T>(src: *const T) -> T {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
||||||
pub unsafe fn read_unaligned<T>(src: *const T) -> T {
|
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||||
|
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||||
// `copy_nonoverlapping` takes care of debug_assert.
|
// `copy_nonoverlapping` takes care of debug_assert.
|
||||||
let mut tmp = MaybeUninit::<T>::uninit();
|
let mut tmp = MaybeUninit::<T>::uninit();
|
||||||
// SAFETY: the caller must guarantee that `src` is valid for reads.
|
// SAFETY: the caller must guarantee that `src` is valid for reads.
|
||||||
|
@ -852,8 +852,9 @@ impl<T: ?Sized> *mut T {
|
|||||||
///
|
///
|
||||||
/// [`ptr::read`]: crate::ptr::read()
|
/// [`ptr::read`]: crate::ptr::read()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read(self) -> T
|
pub const unsafe fn read(self) -> T
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
{
|
{
|
||||||
@ -890,8 +891,9 @@ impl<T: ?Sized> *mut T {
|
|||||||
///
|
///
|
||||||
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
|
/// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read_unaligned(self) -> T
|
pub const unsafe fn read_unaligned(self) -> T
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
{
|
{
|
||||||
|
51
library/core/tests/const_ptr.rs
Normal file
51
library/core/tests/const_ptr.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Aligned to two bytes
|
||||||
|
const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x45, 0x67])];
|
||||||
|
|
||||||
|
const fn unaligned_ptr() -> *const u16 {
|
||||||
|
// Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16
|
||||||
|
unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn read() {
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
|
const FOO: i32 = unsafe { ptr::read(&42 as *const i32) };
|
||||||
|
assert_eq!(FOO, 42);
|
||||||
|
|
||||||
|
const ALIGNED: i32 = unsafe { ptr::read_unaligned(&42 as *const i32) };
|
||||||
|
assert_eq!(ALIGNED, 42);
|
||||||
|
|
||||||
|
const UNALIGNED_PTR: *const u16 = unaligned_ptr();
|
||||||
|
|
||||||
|
const UNALIGNED: u16 = unsafe { ptr::read_unaligned(UNALIGNED_PTR) };
|
||||||
|
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn const_ptr_read() {
|
||||||
|
const FOO: i32 = unsafe { (&42 as *const i32).read() };
|
||||||
|
assert_eq!(FOO, 42);
|
||||||
|
|
||||||
|
const ALIGNED: i32 = unsafe { (&42 as *const i32).read_unaligned() };
|
||||||
|
assert_eq!(ALIGNED, 42);
|
||||||
|
|
||||||
|
const UNALIGNED_PTR: *const u16 = unaligned_ptr();
|
||||||
|
|
||||||
|
const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
|
||||||
|
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mut_ptr_read() {
|
||||||
|
const FOO: i32 = unsafe { (&42 as *const i32 as *mut i32).read() };
|
||||||
|
assert_eq!(FOO, 42);
|
||||||
|
|
||||||
|
const ALIGNED: i32 = unsafe { (&42 as *const i32 as *mut i32).read_unaligned() };
|
||||||
|
assert_eq!(ALIGNED, 42);
|
||||||
|
|
||||||
|
const UNALIGNED_PTR: *mut u16 = unaligned_ptr() as *mut u16;
|
||||||
|
|
||||||
|
const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
|
||||||
|
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
||||||
|
}
|
@ -13,6 +13,8 @@
|
|||||||
#![feature(const_assume)]
|
#![feature(const_assume)]
|
||||||
#![feature(const_cell_into_inner)]
|
#![feature(const_cell_into_inner)]
|
||||||
#![feature(const_maybe_uninit_assume_init)]
|
#![feature(const_maybe_uninit_assume_init)]
|
||||||
|
#![feature(const_ptr_read)]
|
||||||
|
#![feature(const_ptr_offset)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(core_private_bignum)]
|
#![feature(core_private_bignum)]
|
||||||
#![feature(core_private_diy_float)]
|
#![feature(core_private_diy_float)]
|
||||||
@ -34,6 +36,7 @@
|
|||||||
#![feature(raw)]
|
#![feature(raw)]
|
||||||
#![feature(sort_internals)]
|
#![feature(sort_internals)]
|
||||||
#![feature(slice_partition_at_index)]
|
#![feature(slice_partition_at_index)]
|
||||||
|
#![feature(maybe_uninit_extra)]
|
||||||
#![feature(maybe_uninit_write_slice)]
|
#![feature(maybe_uninit_write_slice)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(step_trait)]
|
#![feature(step_trait)]
|
||||||
@ -82,6 +85,10 @@ mod cell;
|
|||||||
mod char;
|
mod char;
|
||||||
mod clone;
|
mod clone;
|
||||||
mod cmp;
|
mod cmp;
|
||||||
|
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
mod const_ptr;
|
||||||
|
|
||||||
mod fmt;
|
mod fmt;
|
||||||
mod hash;
|
mod hash;
|
||||||
mod intrinsics;
|
mod intrinsics;
|
||||||
|
@ -267,3 +267,10 @@ fn uninit_write_slice_cloned_no_drop() {
|
|||||||
|
|
||||||
forget(src);
|
forget(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
fn uninit_const_assume_init_read() {
|
||||||
|
const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
|
||||||
|
assert_eq!(FOO, 42);
|
||||||
|
}
|
||||||
|
16
src/test/ui/const-ptr/out_of_bounds_read.rs
Normal file
16
src/test/ui/const-ptr/out_of_bounds_read.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// error-pattern: any use of this value will cause an error
|
||||||
|
|
||||||
|
#![feature(const_ptr_read)]
|
||||||
|
#![feature(const_ptr_offset)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
const DATA: [u32; 1] = [42];
|
||||||
|
|
||||||
|
const PAST_END_PTR: *const u32 = unsafe { DATA.as_ptr().add(1) };
|
||||||
|
|
||||||
|
const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
|
||||||
|
const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
|
||||||
|
const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
|
||||||
|
}
|
54
src/test/ui/const-ptr/out_of_bounds_read.stderr
Normal file
54
src/test/ui/const-ptr/out_of_bounds_read.stderr
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
error: any use of this value will cause an error
|
||||||
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
||||||
|
| inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||||
|
| inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
|
||||||
|
|
|
||||||
|
::: $DIR/out_of_bounds_read.rs:13:5
|
||||||
|
|
|
||||||
|
LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
|
||||||
|
| ------------------------------------------------------
|
||||||
|
|
|
||||||
|
= note: `#[deny(const_err)]` on by default
|
||||||
|
|
||||||
|
error: any use of this value will cause an error
|
||||||
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
||||||
|
| inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||||
|
| inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
| inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
|
||||||
|
|
|
||||||
|
::: $DIR/out_of_bounds_read.rs:14:5
|
||||||
|
|
|
||||||
|
LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
|
||||||
|
| --------------------------------------------------------
|
||||||
|
|
||||||
|
error: any use of this value will cause an error
|
||||||
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
||||||
|
| inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
||||||
|
| inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
||||||
|
| inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
|
||||||
|
|
|
||||||
|
::: $DIR/out_of_bounds_read.rs:15:5
|
||||||
|
|
|
||||||
|
LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
|
||||||
|
| --------------------------------------------------------------------
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user