Skip to content

Commit e503889

Browse files
committed
Add safety preconditions to std/src/alloc.rs
These contracts formalize the safety requirements that were previously only documented in comments.
1 parent 3b80a4c commit e503889

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

library/std/src/alloc.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
use core::ptr::NonNull;
6060
use core::sync::atomic::{AtomicPtr, Ordering};
6161
use core::{hint, mem, ptr};
62+
#[cfg(kani)]
63+
use core::kani;
64+
use safety::requires;
6265

6366
#[stable(feature = "alloc_module", since = "1.28.0")]
6467
#[doc(inline)]
@@ -150,6 +153,10 @@ impl System {
150153
}
151154

152155
// SAFETY: Same as `Allocator::grow`
156+
#[requires(new_layout.size() >= old_layout.size())]
157+
#[requires(ptr.as_ptr().is_aligned_to(old_layout.align()))]
158+
#[requires(old_layout.size() == 0 || old_layout.align() != 0)]
159+
#[requires(new_layout.size() == 0 || new_layout.align() != 0)]
153160
#[inline]
154161
unsafe fn grow_impl(
155162
&self,
@@ -212,6 +219,7 @@ unsafe impl Allocator for System {
212219
self.alloc_impl(layout, true)
213220
}
214221

222+
#[requires(layout.size() != 0)]
215223
#[inline]
216224
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
217225
if layout.size() != 0 {
@@ -221,6 +229,7 @@ unsafe impl Allocator for System {
221229
}
222230
}
223231

232+
#[requires(new_layout.size() >= old_layout.size())]
224233
#[inline]
225234
unsafe fn grow(
226235
&self,
@@ -232,6 +241,7 @@ unsafe impl Allocator for System {
232241
unsafe { self.grow_impl(ptr, old_layout, new_layout, false) }
233242
}
234243

244+
#[requires(new_layout.size() >= old_layout.size())]
235245
#[inline]
236246
unsafe fn grow_zeroed(
237247
&self,
@@ -243,6 +253,7 @@ unsafe impl Allocator for System {
243253
unsafe { self.grow_impl(ptr, old_layout, new_layout, true) }
244254
}
245255

256+
#[requires(new_layout.size() <= old_layout.size())]
246257
#[inline]
247258
unsafe fn shrink(
248259
&self,
@@ -382,6 +393,10 @@ pub fn rust_oom(layout: Layout) -> ! {
382393
#[allow(unused_attributes)]
383394
#[unstable(feature = "alloc_internals", issue = "none")]
384395
pub mod __default_lib_allocator {
396+
#[cfg(kani)]
397+
use core::kani;
398+
use safety::requires;
399+
385400
use super::{GlobalAlloc, Layout, System};
386401
// These magic symbol names are used as a fallback for implementing the
387402
// `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs`) when there is
@@ -393,6 +408,7 @@ pub mod __default_lib_allocator {
393408
// linkage directives are provided as part of the current compiler allocator
394409
// ABI
395410

411+
#[requires(align.is_power_of_two())]
396412
#[rustc_std_internal_symbol]
397413
pub unsafe extern "C" fn __rdl_alloc(size: usize, align: usize) -> *mut u8 {
398414
// SAFETY: see the guarantees expected by `Layout::from_size_align` and
@@ -403,13 +419,15 @@ pub mod __default_lib_allocator {
403419
}
404420
}
405421

422+
#[requires(align.is_power_of_two())]
406423
#[rustc_std_internal_symbol]
407424
pub unsafe extern "C" fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) {
408425
// SAFETY: see the guarantees expected by `Layout::from_size_align` and
409426
// `GlobalAlloc::dealloc`.
410427
unsafe { System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) }
411428
}
412429

430+
#[requires(align.is_power_of_two())]
413431
#[rustc_std_internal_symbol]
414432
pub unsafe extern "C" fn __rdl_realloc(
415433
ptr: *mut u8,
@@ -425,6 +443,7 @@ pub mod __default_lib_allocator {
425443
}
426444
}
427445

446+
#[requires(align.is_power_of_two())]
428447
#[rustc_std_internal_symbol]
429448
pub unsafe extern "C" fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
430449
// SAFETY: see the guarantees expected by `Layout::from_size_align` and

0 commit comments

Comments
 (0)