Rewrite implementation of #[alloc_error_handler]

The new implementation doesn't use weak lang items and instead changes
`#[alloc_error_handler]` to an attribute macro just like
`#[global_allocator]`.

The attribute will generate the `__rg_oom` function which is called by
the compiler-generated `__rust_alloc_error_handler`. If no `__rg_oom`
function is defined in any crate then the compiler shim will call
`__rdl_oom` in the alloc crate which will simply panic.

This also fixes link errors with `-C link-dead-code` with
`default_alloc_error_handler`: `__rg_oom` was previously defined in the
alloc crate and would attempt to reference the `oom` lang item, even if
it didn't exist. This worked as long as `__rg_oom` was excluded from
linking since it was not called.

This is a prerequisite for the stabilization of
`default_alloc_error_handler` (#102318).
This commit is contained in:
Amanieu d'Antras 2022-10-14 02:24:58 +01:00
parent 2afca78a0b
commit 56074b5231
40 changed files with 441 additions and 166 deletions

View file

@ -6,4 +6,4 @@ all:
$(RUSTC) --emit=obj app.rs
nm $(TMPDIR)/app.o | $(CGREP) rust_begin_unwind
nm $(TMPDIR)/app.o | $(CGREP) rust_eh_personality
nm $(TMPDIR)/app.o | $(CGREP) rust_oom
nm $(TMPDIR)/app.o | $(CGREP) __rg_oom

View file

@ -1,5 +1,5 @@
#![crate_type = "bin"]
#![feature(lang_items)]
#![feature(lang_items, alloc_error_handler)]
#![no_main]
#![no_std]
@ -14,7 +14,7 @@ fn panic(_: &PanicInfo) -> ! {
#[lang = "eh_personality"]
fn eh() {}
#[lang = "oom"]
#[alloc_error_handler]
fn oom(_: Layout) -> ! {
loop {}
}

View file

@ -8,8 +8,8 @@ use core::alloc::Layout;
#[alloc_error_handler]
fn oom(
info: &Layout, //~ ERROR argument should be `Layout`
) -> () //~ ERROR return type should be `!`
info: &Layout, //~^ ERROR mismatched types
) -> () //~^^ ERROR mismatched types
{
loop {}
}

View file

@ -1,14 +1,50 @@
error: return type should be `!`
--> $DIR/alloc-error-handler-bad-signature-1.rs:12:6
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-1.rs:10:1
|
LL | ) -> ()
| ^^
error: argument should be `Layout`
--> $DIR/alloc-error-handler-bad-signature-1.rs:11:11
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | fn oom(
| _^
| |_|
| ||
LL | || info: &Layout,
LL | || ) -> ()
| ||_______- arguments to this function are incorrect
LL | | {
LL | | loop {}
LL | | }
| |__^ expected `&Layout`, found struct `Layout`
|
note: function defined here
--> $DIR/alloc-error-handler-bad-signature-1.rs:10:4
|
LL | fn oom(
| ^^^
LL | info: &Layout,
| ^^^^^^^
| -------------
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-1.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | fn oom(
| _^
| |_|
| ||
LL | || info: &Layout,
LL | || ) -> ()
| ||_______^ expected `!`, found `()`
LL | | {
LL | | loop {}
LL | | }
| |__- expected `!` because of return type
|
= note: expected type `!`
found unit type `()`
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -8,8 +8,8 @@ struct Layout;
#[alloc_error_handler]
fn oom(
info: Layout, //~ ERROR argument should be `Layout`
) { //~ ERROR return type should be `!`
info: Layout, //~^ ERROR mismatched types
) { //~^^ ERROR mismatched types
loop {}
}

View file

@ -1,14 +1,63 @@
error: return type should be `!`
--> $DIR/alloc-error-handler-bad-signature-2.rs:12:3
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
|
LL | ) {
| ^
error: argument should be `Layout`
--> $DIR/alloc-error-handler-bad-signature-2.rs:11:11
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | fn oom(
| _^
| |_|
| ||
LL | || info: Layout,
LL | || ) {
| || -
| ||_|
| | arguments to this function are incorrect
LL | | loop {}
LL | | }
| |__^ expected struct `Layout`, found struct `core::alloc::Layout`
|
= note: struct `core::alloc::Layout` and struct `Layout` have similar names, but are actually distinct types
note: struct `core::alloc::Layout` is defined in crate `core`
--> $SRC_DIR/core/src/alloc/layout.rs:LL:COL
|
LL | pub struct Layout {
| ^^^^^^^^^^^^^^^^^
note: struct `Layout` is defined in the current crate
--> $DIR/alloc-error-handler-bad-signature-2.rs:7:1
|
LL | struct Layout;
| ^^^^^^^^^^^^^
note: function defined here
--> $DIR/alloc-error-handler-bad-signature-2.rs:10:4
|
LL | fn oom(
| ^^^
LL | info: Layout,
| ^^^^^^
| ------------
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | fn oom(
| _^
| |_|
| ||
LL | || info: Layout,
LL | || ) {
| || ^
| ||_|
| | expected `!`, found `()`
LL | | loop {}
LL | | }
| |__- expected `!` because of return type
|
= note: expected type `!`
found unit type `()`
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -7,7 +7,7 @@
struct Layout;
#[alloc_error_handler]
fn oom() -> ! { //~ ERROR function should have one argument
fn oom() -> ! { //~ ERROR this function takes 0 arguments but 1 argument was supplied
loop {}
}

View file

@ -1,8 +1,25 @@
error: function should have one argument
error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/alloc-error-handler-bad-signature-3.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | fn oom() -> ! {
| _-^^^^^^^^^^^^
LL | | loop {}
LL | | }
| |_- argument of type `core::alloc::Layout` unexpected
|
note: function defined here
--> $DIR/alloc-error-handler-bad-signature-3.rs:10:4
|
LL | fn oom() -> ! {
| ^^^^^^^^^^^^^
| ^^^
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
help: remove the extra argument
|
LL | fn oom() -> !() {
| ++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0061`.

View file

@ -5,10 +5,12 @@
use core::alloc::Layout;
#[alloc_error_handler] //~ ERROR the `#[alloc_error_handler]` attribute is an experimental feature
#[alloc_error_handler] //~ ERROR use of unstable library feature 'alloc_error_handler'
fn oom(info: Layout) -> ! {
loop {}
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}

View file

@ -1,8 +1,8 @@
error[E0658]: the `#[alloc_error_handler]` attribute is an experimental feature
--> $DIR/feature-gate-alloc-error-handler.rs:8:1
error[E0658]: use of unstable library feature 'alloc_error_handler'
--> $DIR/feature-gate-alloc-error-handler.rs:8:3
|
LL | #[alloc_error_handler]
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #51540 <https://github.com/rust-lang/rust/issues/51540> for more information
= help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable