about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorHarald Hoyer <harald@redhat.com>2020-09-07 10:45:20 +0200
committerHarald Hoyer <harald@redhat.com>2020-10-02 09:00:29 +0200
commitcadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8 (patch)
treef08cb851bfe4d02d97b2b20748a9f0d69d225ed0 /library/alloc/src
parentf283d3f02cf3ed261a519afe05cde9e23d1d9278 (diff)
downloadrust-cadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8.tar.gz
rust-cadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8.zip
Implement Make `handle_alloc_error` default to panic (for no_std + liballoc)
Related: https://github.com/rust-lang/rust/issues/66741

Guarded with `#![feature(default_alloc_error_handler)]` a default
`alloc_error_handler` is called, if a custom allocator is used and no
other custom `#[alloc_error_handler]` is defined.

The panic message does not contain the size anymore, because it would
pull in the fmt machinery, which would blow up the code size
significantly.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/alloc.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 75158eefcac..ce70de6ebdd 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -26,6 +26,8 @@ extern "Rust" {
     fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
     #[rustc_allocator_nounwind]
     fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
+    #[rustc_allocator_nounwind]
+    fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
 }
 
 /// The global memory allocator.
@@ -334,6 +336,24 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
 /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
 /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
 #[stable(feature = "global_alloc", since = "1.28.0")]
+#[cfg(not(any(test, bootstrap)))]
+#[rustc_allocator_nounwind]
+pub fn handle_alloc_error(layout: Layout) -> ! {
+    unsafe {
+        __rust_alloc_error_handler(layout.size(), layout.align());
+    }
+}
+
+// For alloc test `std::alloc::handle_alloc_error` can be used directly.
+#[cfg(test)]
+pub use std::alloc::handle_alloc_error;
+
+// In stage0 (bootstrap) `__rust_alloc_error_handler`,
+// might not be generated yet, because an old compiler is used,
+// so use the old direct call.
+#[cfg(all(bootstrap, not(test)))]
+#[stable(feature = "global_alloc", since = "1.28.0")]
+#[doc(hidden)]
 #[rustc_allocator_nounwind]
 pub fn handle_alloc_error(layout: Layout) -> ! {
     extern "Rust" {
@@ -342,3 +362,30 @@ pub fn handle_alloc_error(layout: Layout) -> ! {
     }
     unsafe { oom_impl(layout) }
 }
+
+#[cfg(not(any(test, bootstrap)))]
+#[doc(hidden)]
+#[allow(unused_attributes)]
+#[unstable(feature = "alloc_internals", issue = "none")]
+pub mod __default_lib_allocator {
+    use crate::alloc::Layout;
+
+    // called via generated `__rust_alloc_error_handler`
+
+    // if there is no `#[alloc_error_handler]`
+    #[rustc_std_internal_symbol]
+    pub unsafe extern "C" fn __rdl_oom(size: usize, _align: usize) -> ! {
+        panic!("memory allocation of {} bytes failed", size)
+    }
+
+    // if there is a `#[alloc_error_handler]`
+    #[rustc_std_internal_symbol]
+    pub unsafe extern "C" fn __rg_oom(size: usize, align: usize) -> ! {
+        let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
+        extern "Rust" {
+            #[lang = "oom"]
+            fn oom_impl(layout: Layout) -> !;
+        }
+        unsafe { oom_impl(layout) }
+    }
+}