]> git.lizzy.rs Git - rust.git/commitdiff
Use a faster allocation size check in slice::from_raw_parts
authorBen Kimock <kimockb@gmail.com>
Thu, 20 Oct 2022 04:30:00 +0000 (00:30 -0400)
committerBen Kimock <kimockb@gmail.com>
Thu, 20 Oct 2022 04:30:00 +0000 (00:30 -0400)
library/core/src/intrinsics.rs
library/core/src/lib.rs
library/core/src/slice/raw.rs

index 2399262c05b4663bf2fc727147a46d9166715407..3a7a179c98be995973245a6756e59418eb008b9d 100644 (file)
@@ -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 {
index 2fd8180f8b2a29a829c028a03dfe02fad512b1f4..aa197c990b20bb8bd5a707c9e4fe0b6a9bac05fe 100644 (file)
 #![feature(extern_types)]
 #![feature(fundamental)]
 #![feature(if_let_guard)]
+#![feature(inline_const)]
 #![feature(intra_doc_pointers)]
 #![feature(intrinsics)]
 #![feature(lang_items)]
index 3c5abd215a4b76ec244fd6e03decb8543d8b605b..dace748fed4559f56cdd50874583275b6d42d188 100644 (file)
@@ -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 @@
     // 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)
     }
     // 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)
     }