Auto merge of #126556 - saethlin:layout-precondition, r=joboet · patricklam/verify-rust-std@7f8bdd5 (original) (raw)
`@@ -6,7 +6,7 @@
`
6
6
``
7
7
`use crate::error::Error;
`
8
8
`use crate::ptr::{Alignment, NonNull};
`
9
``
`-
use crate::{cmp, fmt, mem};
`
``
9
`+
use crate::{assert_unsafe_precondition, cmp, fmt, mem};
`
10
10
``
11
11
`// While this function is used in one place and its implementation
`
12
12
`// could be inlined, the previous attempts to do so made rustc
`
`@@ -66,12 +66,20 @@ impl Layout {
`
66
66
`#[inline]
`
67
67
`#[rustc_allow_const_fn_unstable(ptr_alignment_type)]
`
68
68
`pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
`
69
``
`-
if !align.is_power_of_two() {
`
70
``
`-
return Err(LayoutError);
`
``
69
`+
if Layout::is_size_align_valid(size, align) {
`
``
70
`+
// SAFETY: Layout::is_size_align_valid checks the preconditions for this call.
`
``
71
`+
unsafe { Ok(Layout { size, align: mem::transmute(align) }) }
`
``
72
`+
} else {
`
``
73
`+
Err(LayoutError)
`
71
74
`}
`
``
75
`+
}
`
72
76
``
73
``
`-
// SAFETY: just checked that align is a power of two.
`
74
``
`-
Layout::from_size_alignment(size, unsafe { Alignment::new_unchecked(align) })
`
``
77
`+
const fn is_size_align_valid(size: usize, align: usize) -> bool {
`
``
78
`+
let Some(align) = Alignment::new(align) else { return false };
`
``
79
`+
if size > Self::max_size_for_align(align) {
`
``
80
`+
return false;
`
``
81
`+
}
`
``
82
`+
true
`
75
83
`}
`
76
84
``
77
85
`#[inline(always)]
`
`@@ -116,8 +124,17 @@ impl Layout {
`
116
124
`#[inline]
`
117
125
`#[rustc_allow_const_fn_unstable(ptr_alignment_type)]
`
118
126
`pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
`
``
127
`+
assert_unsafe_precondition!(
`
``
128
`+
check_library_ub,
`
``
129
`+
"Layout::from_size_align_unchecked requires that align is a power of 2 \
`
``
130
`+
and the rounded-up allocation size does not exceed isize::MAX",
`
``
131
`+
(
`
``
132
`+
size: usize = size,
`
``
133
`+
align: usize = align,
`
``
134
`+
) => Layout::is_size_align_valid(size, align)
`
``
135
`+
);
`
119
136
`// SAFETY: the caller is required to uphold the preconditions.
`
120
``
`-
unsafe { Layout { size, align: Alignment::new_unchecked(align) } }
`
``
137
`+
unsafe { Layout { size, align: mem::transmute(align) } }
`
121
138
`}
`
122
139
``
123
140
`/// The minimum size in bytes for a memory block of this layout.
`