diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2017-08-22 14:36:49 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2017-08-28 08:06:52 -0700 |
| commit | b6f554b6dc972608761db93a375bcb0e89155e1d (patch) | |
| tree | 4543e921c025346532151af3a5ec8ae5b8666447 /src/liballoc | |
| parent | a24e0f25d7a0ac793b37eb4db353d5f9f2befc97 (diff) | |
| download | rust-b6f554b6dc972608761db93a375bcb0e89155e1d.tar.gz rust-b6f554b6dc972608761db93a375bcb0e89155e1d.zip | |
std: Mark allocation functions as nounwind
This commit flags all allocation-related functions in liballoc as "this can't unwind" which should largely resolve the size-related issues found on #42808. The documentation on the trait was updated with such a restriction (they can't panic) as well as some other words about the relative instability about implementing a bullet-proof allocator. Closes #42808
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/allocator.rs | 23 | ||||
| -rw-r--r-- | src/liballoc/heap.rs | 10 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 1 |
3 files changed, 34 insertions, 0 deletions
diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs index fc6585a9f95..c7177029011 100644 --- a/src/liballoc/allocator.rs +++ b/src/liballoc/allocator.rs @@ -464,6 +464,29 @@ impl fmt::Display for CannotReallocInPlace { /// * if a layout `k` fits a memory block (denoted by `ptr`) /// currently allocated via an allocator `a`, then it is legal to /// use that layout to deallocate it, i.e. `a.dealloc(ptr, k);`. +/// +/// # Unsafety +/// +/// The `Alloc` trait is an `unsafe` trait for a number of reasons, and +/// implementors must ensure that they adhere to these contracts: +/// +/// * Pointers returned from allocation functions must point to valid memory and +/// retain their validity until at least the instance of `Alloc` is dropped +/// itself. +/// +/// * It's undefined behavior if global allocators unwind. This restriction may +/// be lifted in the future, but currently a panic from any of these +/// functions may lead to memory unsafety. Note that as of the time of this +/// writing allocators *not* intending to be global allocators can still panic +/// in their implementation without violating memory safety. +/// +/// * `Layout` queries and calculations in general must be correct. Callers of +/// this trait are allowed to rely on the contracts defined on each method, +/// and implementors must ensure such contracts remain true. +/// +/// Note that this list may get tweaked over time as clarifications are made in +/// the future. Additionally global allocators may gain unique requirements for +/// how to safely implement one in the future as well. pub unsafe trait Alloc { // (Note: existing allocators have unspecified but well-defined diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 820f2d958d9..b2bd9d7d8fa 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -27,24 +27,32 @@ pub mod __core { extern "Rust" { #[allocator] + #[rustc_allocator_nounwind] fn __rust_alloc(size: usize, align: usize, err: *mut u8) -> *mut u8; #[cold] + #[rustc_allocator_nounwind] fn __rust_oom(err: *const u8) -> !; + #[rustc_allocator_nounwind] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); + #[rustc_allocator_nounwind] fn __rust_usable_size(layout: *const u8, min: *mut usize, max: *mut usize); + #[rustc_allocator_nounwind] fn __rust_realloc(ptr: *mut u8, old_size: usize, old_align: usize, new_size: usize, new_align: usize, err: *mut u8) -> *mut u8; + #[rustc_allocator_nounwind] fn __rust_alloc_zeroed(size: usize, align: usize, err: *mut u8) -> *mut u8; + #[rustc_allocator_nounwind] fn __rust_alloc_excess(size: usize, align: usize, excess: *mut usize, err: *mut u8) -> *mut u8; + #[rustc_allocator_nounwind] fn __rust_realloc_excess(ptr: *mut u8, old_size: usize, old_align: usize, @@ -52,11 +60,13 @@ extern "Rust" { new_align: usize, excess: *mut usize, err: *mut u8) -> *mut u8; + #[rustc_allocator_nounwind] fn __rust_grow_in_place(ptr: *mut u8, old_size: usize, old_align: usize, new_size: usize, new_align: usize) -> u8; + #[rustc_allocator_nounwind] fn __rust_shrink_in_place(ptr: *mut u8, old_size: usize, old_align: usize, diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 227fcfabcf1..66928e9a480 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -107,6 +107,7 @@ #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] +#![feature(rustc_attrs)] #![feature(shared)] #![feature(slice_get_slice)] #![feature(slice_patterns)] |
