1
Fork 0

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 33a92bc8b0
commit b166ad0b1e

View file

@ -5,6 +5,7 @@ use crate::prelude::*;
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
use rustc_session::config::OomStrategy; use rustc_session::config::OomStrategy;
use rustc_span::symbol::sym;
/// Returns whether an allocator shim was created /// Returns whether an allocator shim was created
pub(crate) fn codegen( pub(crate) fn codegen(
@ -23,7 +24,7 @@ pub(crate) fn codegen(
module, module,
unwind_context, unwind_context,
kind, kind,
tcx.lang_items().oom().is_some(), tcx.alloc_error_handler_kind(()).unwrap(),
tcx.sess.opts.unstable_opts.oom, tcx.sess.opts.unstable_opts.oom,
); );
true true
@ -36,7 +37,7 @@ fn codegen_inner(
module: &mut impl Module, module: &mut impl Module,
unwind_context: &mut UnwindContext, unwind_context: &mut UnwindContext,
kind: AllocatorKind, kind: AllocatorKind,
has_alloc_error_handler: bool, alloc_error_handler_kind: AllocatorKind,
oom_strategy: OomStrategy, oom_strategy: OomStrategy,
) { ) {
let usize_ty = module.target_config().pointer_type(); let usize_ty = module.target_config().pointer_type();
@ -108,12 +109,12 @@ fn codegen_inner(
returns: vec![], returns: vec![],
}; };
let callee_name = if has_alloc_error_handler { "__rg_oom" } else { "__rdl_oom" }; let callee_name = alloc_error_handler_kind.fn_name(sym::oom);
let func_id = let func_id =
module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap(); module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap();
let callee_func_id = module.declare_function(callee_name, Linkage::Import, &sig).unwrap(); let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.func.signature = sig; ctx.func.signature = sig;