Reject huge alignments on macos with system allocator only
ef8804ba27 addressed #30170 by rejecting
huge alignments at the allocator API level, transforming a specific
platform bug/limitation into an enforced API limitation on all
platforms.
This change essentially reverts that commit, and instead makes alloc()
itself return AllocErr::Unsupported when receiving huge alignments.
This was discussed in https://github.com/rust-lang/rust/issues/32838#issuecomment-368348408
and following.
This commit is contained in:
parent
06fa27d7c8
commit
98175a8793
2 changed files with 15 additions and 14 deletions
|
|
@ -134,6 +134,14 @@ mod platform {
|
|||
let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
|
||||
libc::malloc(layout.size()) as *mut u8
|
||||
} else {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if layout.align() > (1 << 31) {
|
||||
return Err(AllocErr::Unsupported {
|
||||
details: "requested alignment too large"
|
||||
})
|
||||
}
|
||||
}
|
||||
aligned_malloc(&layout)
|
||||
};
|
||||
if !ptr.is_null() {
|
||||
|
|
|
|||
|
|
@ -65,13 +65,11 @@ pub struct Layout {
|
|||
|
||||
impl Layout {
|
||||
/// Constructs a `Layout` from a given `size` and `align`,
|
||||
/// or returns `None` if any of the following conditions
|
||||
/// or returns `None` if either of the following conditions
|
||||
/// are not met:
|
||||
///
|
||||
/// * `align` must be a power of two,
|
||||
///
|
||||
/// * `align` must not exceed 2<sup>31</sup> (i.e. `1 << 31`),
|
||||
///
|
||||
/// * `size`, when rounded up to the nearest multiple of `align`,
|
||||
/// must not overflow (i.e. the rounded value must be less than
|
||||
/// `usize::MAX`).
|
||||
|
|
@ -81,10 +79,6 @@ impl Layout {
|
|||
return None;
|
||||
}
|
||||
|
||||
if align > (1 << 31) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// (power-of-two implies align != 0.)
|
||||
|
||||
// Rounded up size is:
|
||||
|
|
@ -113,9 +107,8 @@ impl Layout {
|
|||
/// # Safety
|
||||
///
|
||||
/// This function is unsafe as it does not verify that `align` is
|
||||
/// a power-of-two that is also less than or equal to 2<sup>31</sup>, nor
|
||||
/// that `size` aligned to `align` fits within the address space
|
||||
/// (i.e. the `Layout::from_size_align` preconditions).
|
||||
/// a power-of-two nor `size` aligned to `align` fits within the
|
||||
/// address space (i.e. the `Layout::from_size_align` preconditions).
|
||||
#[inline]
|
||||
pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout {
|
||||
Layout { size: size, align: align }
|
||||
|
|
@ -220,10 +213,10 @@ impl Layout {
|
|||
let padded_size = self.size.checked_add(self.padding_needed_for(self.align))?;
|
||||
let alloc_size = padded_size.checked_mul(n)?;
|
||||
|
||||
// We can assume that `self.align` is a power-of-two that does
|
||||
// not exceed 2<sup>31</sup>. Furthermore, `alloc_size` has already been
|
||||
// rounded up to a multiple of `self.align`; therefore, the
|
||||
// call to `Layout::from_size_align` below should never panic.
|
||||
// We can assume that `self.align` is a power-of-two.
|
||||
// Furthermore, `alloc_size` has already been rounded up
|
||||
// to a multiple of `self.align`; therefore, the call to
|
||||
// `Layout::from_size_align` below should never panic.
|
||||
Some((Layout::from_size_align(alloc_size, self.align).unwrap(), padded_size))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue