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:
parent
2afca78a0b
commit
56074b5231
40 changed files with 441 additions and 166 deletions
|
@ -15,7 +15,7 @@ pub(crate) unsafe fn codegen(
|
|||
module_llvm: &mut ModuleLlvm,
|
||||
module_name: &str,
|
||||
kind: AllocatorKind,
|
||||
has_alloc_error_handler: bool,
|
||||
alloc_error_handler_kind: AllocatorKind,
|
||||
) {
|
||||
let llcx = &*module_llvm.llcx;
|
||||
let llmod = module_llvm.llmod();
|
||||
|
@ -117,8 +117,7 @@ pub(crate) unsafe fn codegen(
|
|||
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
|
||||
}
|
||||
|
||||
let kind = if has_alloc_error_handler { AllocatorKind::Global } else { AllocatorKind::Default };
|
||||
let callee = kind.fn_name(sym::oom);
|
||||
let callee = alloc_error_handler_kind.fn_name(sym::oom);
|
||||
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
|
||||
// -> ! DIFlagNoReturn
|
||||
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
|
||||
|
|
|
@ -108,11 +108,11 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
module_name: &str,
|
||||
kind: AllocatorKind,
|
||||
has_alloc_error_handler: bool,
|
||||
alloc_error_handler_kind: AllocatorKind,
|
||||
) -> ModuleLlvm {
|
||||
let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
|
||||
unsafe {
|
||||
allocator::codegen(tcx, &mut module_llvm, module_name, kind, has_alloc_error_handler);
|
||||
allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind);
|
||||
}
|
||||
module_llvm
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue