Skip to content

Commit cfcb0a2

Browse files
committed
Use a faster allocation size check in slice::from_raw_parts
1 parent 57781b2 commit cfcb0a2

File tree

3 files changed

+16
-5
lines changed

3 files changed

+16
-5
lines changed

library/core/src/intrinsics.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,16 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
22292229
!ptr.is_null() && ptr.is_aligned()
22302230
}
22312231

2232+
/// Checks whether an allocation of `len` instances of `T` exceeds
2233+
/// the maximum allowed allocation size.
2234+
pub(crate) fn is_valid_allocation_size<T>(len: usize) -> bool {
2235+
let max_len = const {
2236+
let size = crate::mem::size_of::<T>();
2237+
if size == 0 { usize::MAX } else { isize::MAX as usize / size }
2238+
};
2239+
len <= max_len
2240+
}
2241+
22322242
/// Checks whether the regions of memory starting at `src` and `dst` of size
22332243
/// `count * size_of::<T>()` do *not* overlap.
22342244
pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
#![feature(extern_types)]
192192
#![feature(fundamental)]
193193
#![feature(if_let_guard)]
194+
#![feature(inline_const)]
194195
#![feature(intra_doc_pointers)]
195196
#![feature(intrinsics)]
196197
#![feature(lang_items)]

library/core/src/slice/raw.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! Free functions to create `&[T]` and `&mut [T]`.
22
33
use crate::array;
4-
use crate::intrinsics::{assert_unsafe_precondition, is_aligned_and_not_null};
4+
use crate::intrinsics::{
5+
assert_unsafe_precondition, is_aligned_and_not_null, is_valid_allocation_size,
6+
};
57
use crate::ops::Range;
68
use crate::ptr;
79

@@ -91,8 +93,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
9193
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
9294
unsafe {
9395
assert_unsafe_precondition!([T](data: *const T, len: usize) =>
94-
is_aligned_and_not_null(data)
95-
&& crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize
96+
is_aligned_and_not_null(data) && is_valid_allocation_size::<T>(len)
9697
);
9798
&*ptr::slice_from_raw_parts(data, len)
9899
}
@@ -135,8 +136,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m
135136
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
136137
unsafe {
137138
assert_unsafe_precondition!([T](data: *mut T, len: usize) =>
138-
is_aligned_and_not_null(data)
139-
&& crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize
139+
is_aligned_and_not_null(data) && is_valid_allocation_size::<T>(len)
140140
);
141141
&mut *ptr::slice_from_raw_parts_mut(data, len)
142142
}

0 commit comments

Comments
 (0)