]> git.proxmox.com Git - rustc.git/blame - src/test/ui/allocator/no_std-alloc-error-handler-custom.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / src / test / ui / allocator / no_std-alloc-error-handler-custom.rs
CommitLineData
29967ef6
XL
1// run-pass
2// ignore-android no libc
29967ef6
XL
3// ignore-emscripten no libc
4// ignore-sgx no libc
5// ignore-wasm32 no libc
6// only-linux
7// compile-flags:-C panic=abort
8// aux-build:helper.rs
9
6a06907d 10#![feature(start, rustc_private, new_uninit, panic_info_message, lang_items)]
29967ef6
XL
11#![feature(alloc_error_handler)]
12#![no_std]
13
14extern crate alloc;
15extern crate libc;
16
17// ARM targets need these symbols
18#[no_mangle]
19pub fn __aeabi_unwind_cpp_pr0() {}
20
21#[no_mangle]
22pub fn __aeabi_unwind_cpp_pr1() {}
23
24use core::ptr::null_mut;
25use core::alloc::{GlobalAlloc, Layout};
26use alloc::boxed::Box;
27
28extern crate helper;
29
30struct MyAllocator;
31
32#[alloc_error_handler]
33fn my_oom(layout: Layout) -> !
34{
35 use alloc::fmt::write;
36 unsafe {
37 let size = layout.size();
38 let mut s = alloc::string::String::new();
39 write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap();
40 let s = s.as_str();
41 libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
42 libc::exit(0)
43 }
44}
45
46unsafe impl GlobalAlloc for MyAllocator {
47 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
48 if layout.size() < 4096 {
49 libc::malloc(layout.size()) as _
50 } else {
51 null_mut()
52 }
53 }
54 unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
55}
56
57#[global_allocator]
58static A: MyAllocator = MyAllocator;
59
60#[panic_handler]
61fn panic(panic_info: &core::panic::PanicInfo) -> ! {
62 unsafe {
63 if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
64 const PSTR: &str = "panic occurred: ";
65 const CR: &str = "\n";
66 libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
67 libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
68 libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len());
69 }
70 if let Some(args) = panic_info.message() {
71 let mut s = alloc::string::String::new();
72 alloc::fmt::write(&mut s, *args).unwrap();
73 let s = s.as_str();
74 const PSTR: &str = "panic occurred: ";
75 const CR: &str = "\n";
76 libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
77 libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
78 libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len());
79 } else {
80 const PSTR: &str = "panic occurred\n";
81 libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
82 }
83 libc::exit(1)
84 }
85}
86
6a06907d
XL
87// Because we are compiling this code with `-C panic=abort`, this wouldn't normally be needed.
88// However, `core` and `alloc` are both compiled with `-C panic=unwind`, which means that functions
89// in these libaries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
90// unwind. So, for this test case we will define the symbol.
91#[lang = "eh_personality"]
92extern fn rust_eh_personality() {}
93
29967ef6
XL
94#[derive(Debug)]
95struct Page([[u64; 32]; 16]);
96
97#[start]
98pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
99 let zero = Box::<Page>::new_zeroed();
100 let zero = unsafe { zero.assume_init() };
101 helper::work_with(&zero);
102 1
103}