Skip to content

Commit 2295a4b

Browse files
committed
Support #[alloc_error_handler] without the allocator shim
Currently it is possible to avoid linking the allocator shim when __rust_no_alloc_shim_is_unstable_v2 is defined when linking rlibs directly as some build systems need. However this currently requires liballoc to be compiled with --cfg no_global_oom_handling, which places huge restrictions on what functions you can call and makes it impossible to use libstd. Or alternatively you have to define __rust_alloc_error_handler and (when using libstd) __rust_alloc_error_handler_should_panic using #[rustc_std_internal_symbol]. With this commit the former can be replaced with #[alloc_error_handler]. Eventually the alloc_error_handler may either be removed entirely (though the PR for that has been stale for years now) or we may start using weak symbols for it instead. For the latter case this commit is a prerequisite anyway.
1 parent 81807c7 commit 2295a4b

File tree

6 files changed

+58
-57
lines changed

6 files changed

+58
-57
lines changed

compiler/rustc_ast/src/expand/allocator.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,8 @@ pub fn default_fn_name(base: Symbol) -> String {
1515
format!("__rdl_{base}")
1616
}
1717

18-
pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str {
19-
match alloc_error_handler_kind {
20-
AllocatorKind::Global => "__rg_oom",
21-
AllocatorKind::Default => "__rdl_oom",
22-
}
23-
}
24-
2518
pub const ALLOC_ERROR_HANDLER: &str = "__rust_alloc_error_handler";
19+
pub const ALLOC_ERROR_HANDLER_DEFAULT: &str = "__rdl_oom";
2620
pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2";
2721

2822
pub enum AllocatorTy {

compiler/rustc_builtin_macros/src/alloc_error_handler.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_ast::expand::allocator::ALLOC_ERROR_HANDLER;
12
use rustc_ast::ptr::P;
23
use rustc_ast::{
34
self as ast, Fn, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind,
@@ -56,7 +57,7 @@ pub(crate) fn expand(
5657
}
5758

5859
// #[rustc_std_internal_symbol]
59-
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
60+
// unsafe fn __rust_alloc_error_handler(size: usize, align: usize) -> ! {
6061
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
6162
// }
6263
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
@@ -85,7 +86,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
8586
let kind = ItemKind::Fn(Box::new(Fn {
8687
defaultness: ast::Defaultness::Final,
8788
sig,
88-
ident: Ident::from_str_and_span("__rg_oom", span),
89+
ident: Ident::from_str_and_span(ALLOC_ERROR_HANDLER, span),
8990
generics: Generics::default(),
9091
contract: None,
9192
body,

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
55
use rustc_ast::expand::allocator::{
6-
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
7-
alloc_error_handler_name, default_fn_name, global_fn_name,
6+
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind,
7+
AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
88
};
99
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
1010
use rustc_session::config::OomStrategy;
@@ -72,17 +72,19 @@ fn codegen_inner(
7272
}
7373
}
7474

75-
let sig = Signature {
76-
call_conv: module.target_config().default_call_conv,
77-
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
78-
returns: vec![],
79-
};
80-
crate::common::create_wrapper_function(
81-
module,
82-
sig,
83-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
84-
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
85-
);
75+
if alloc_error_handler_kind == AllocatorKind::Default {
76+
let sig = Signature {
77+
call_conv: module.target_config().default_call_conv,
78+
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
79+
returns: vec![],
80+
};
81+
crate::common::create_wrapper_function(
82+
module,
83+
sig,
84+
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
85+
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT),
86+
);
87+
}
8688

8789
let data_id = module
8890
.declare_data(

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
22
#[cfg(feature = "master")]
33
use gccjit::{FnAttribute, VarAttribute};
44
use rustc_ast::expand::allocator::{
5-
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
6-
alloc_error_handler_name, default_fn_name, global_fn_name,
5+
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind,
6+
AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
77
};
88
use rustc_middle::bug;
99
use rustc_middle::ty::TyCtxt;
@@ -61,15 +61,17 @@ pub(crate) unsafe fn codegen(
6161
}
6262
}
6363

64-
// FIXME(bjorn3): Add noreturn attribute
65-
create_wrapper_function(
66-
tcx,
67-
context,
68-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
69-
Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))),
70-
&[usize, usize],
71-
None,
72-
);
64+
if alloc_error_handler_kind == AllocatorKind::Default {
65+
// FIXME(bjorn3): Add noreturn attribute
66+
create_wrapper_function(
67+
tcx,
68+
context,
69+
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
70+
Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)),
71+
&[usize, usize],
72+
None,
73+
);
74+
}
7375

7476
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
7577
let global = context.new_global(None, GlobalKind::Exported, i8, name);

compiler/rustc_codegen_llvm/src/allocator.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use libc::c_uint;
22
use rustc_ast::expand::allocator::{
3-
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
4-
alloc_error_handler_name, default_fn_name, global_fn_name,
3+
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind,
4+
AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
55
};
66
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
77
use rustc_middle::bug;
@@ -61,16 +61,18 @@ pub(crate) unsafe fn codegen(
6161
}
6262
}
6363

64-
// rust alloc error handler
65-
create_wrapper_function(
66-
tcx,
67-
&cx,
68-
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
69-
Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))),
70-
&[usize, usize], // size, align
71-
None,
72-
true,
73-
);
64+
if alloc_error_handler_kind == AllocatorKind::Default {
65+
// rust alloc error handler
66+
create_wrapper_function(
67+
tcx,
68+
&cx,
69+
&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER),
70+
Some(&mangle_internal_symbol(tcx, ALLOC_ERROR_HANDLER_DEFAULT)),
71+
&[usize, usize], // size, align
72+
None,
73+
true,
74+
);
75+
}
7476

7577
unsafe {
7678
// __rust_alloc_error_handler_should_panic

compiler/rustc_metadata/src/creader.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::str::FromStr;
77
use std::time::Duration;
88
use std::{cmp, env, iter};
99

10-
use rustc_ast::expand::allocator::{AllocatorKind, alloc_error_handler_name, global_fn_name};
10+
use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, AllocatorKind, global_fn_name};
1111
use rustc_ast::{self as ast, *};
1212
use rustc_data_structures::fx::FxHashSet;
1313
use rustc_data_structures::owned_slice::OwnedSlice;
@@ -1067,17 +1067,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10671067
}
10681068
spans => !spans.is_empty(),
10691069
};
1070-
self.cstore.has_alloc_error_handler = match &*fn_spans(
1071-
krate,
1072-
Symbol::intern(alloc_error_handler_name(AllocatorKind::Global)),
1073-
) {
1074-
[span1, span2, ..] => {
1075-
self.dcx()
1076-
.emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 });
1077-
true
1078-
}
1079-
spans => !spans.is_empty(),
1080-
};
1070+
self.cstore.has_alloc_error_handler =
1071+
match &*fn_spans(krate, Symbol::intern(ALLOC_ERROR_HANDLER)) {
1072+
[span1, span2, ..] => {
1073+
self.dcx().emit_err(errors::NoMultipleAllocErrorHandler {
1074+
span2: *span2,
1075+
span1: *span1,
1076+
});
1077+
true
1078+
}
1079+
spans => !spans.is_empty(),
1080+
};
10811081

10821082
// Check to see if we actually need an allocator. This desire comes
10831083
// about through the `#![needs_allocator]` attribute and is typically

0 commit comments

Comments
 (0)