diff options
| author | Ben Kimock <kimockb@gmail.com> | 2022-10-20 00:30:00 -0400 |
|---|---|---|
| committer | Ben Kimock <kimockb@gmail.com> | 2022-10-20 00:30:00 -0400 |
| commit | cfcb0a2135da6d4bdbf5f28806dea0cc70c5b6c5 (patch) | |
| tree | 1d86716173966df3b9062ed7184389b31aadc5fd | |
| parent | 57781b24c54f9548722927ba88c343ff28da94ce (diff) | |
| download | rust-cfcb0a2135da6d4bdbf5f28806dea0cc70c5b6c5.tar.gz rust-cfcb0a2135da6d4bdbf5f28806dea0cc70c5b6c5.zip | |
Use a faster allocation size check in slice::from_raw_parts
| -rw-r--r-- | library/core/src/intrinsics.rs | 10 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/slice/raw.rs | 10 |
3 files changed, 16 insertions, 5 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 2399262c05b..3a7a179c98b 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2229,6 +2229,16 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool { !ptr.is_null() && ptr.is_aligned() } +/// Checks whether an allocation of `len` instances of `T` exceeds +/// the maximum allowed allocation size. +pub(crate) fn is_valid_allocation_size<T>(len: usize) -> bool { + let max_len = const { + let size = crate::mem::size_of::<T>(); + if size == 0 { usize::MAX } else { isize::MAX as usize / size } + }; + len <= max_len +} + /// Checks whether the regions of memory starting at `src` and `dst` of size /// `count * size_of::<T>()` do *not* overlap. pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2fd8180f8b2..aa197c990b2 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -191,6 +191,7 @@ #![feature(extern_types)] #![feature(fundamental)] #![feature(if_let_guard)] +#![feature(inline_const)] #![feature(intra_doc_pointers)] #![feature(intrinsics)] #![feature(lang_items)] diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 3c5abd215a4..dace748fed4 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -1,7 +1,9 @@ //! Free functions to create `&[T]` and `&mut [T]`. use crate::array; -use crate::intrinsics::{assert_unsafe_precondition, is_aligned_and_not_null}; +use crate::intrinsics::{ + assert_unsafe_precondition, is_aligned_and_not_null, is_valid_allocation_size, +}; use crate::ops::Range; use crate::ptr; @@ -91,8 +93,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] // SAFETY: the caller must uphold the safety contract for `from_raw_parts`. unsafe { assert_unsafe_precondition!([T](data: *const T, len: usize) => - is_aligned_and_not_null(data) - && crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize + is_aligned_and_not_null(data) && is_valid_allocation_size::<T>(len) ); &*ptr::slice_from_raw_parts(data, len) } @@ -135,8 +136,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`. unsafe { assert_unsafe_precondition!([T](data: *mut T, len: usize) => - is_aligned_and_not_null(data) - && crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize + is_aligned_and_not_null(data) && is_valid_allocation_size::<T>(len) ); &mut *ptr::slice_from_raw_parts_mut(data, len) } |
