Skip to content

Commit ed3ddb3

Browse files
committed
Auto merge of rust-lang#110789 - matthiaskrgr:rollup-92e764u, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#110563 (Break up long function in trait selection error reporting + clean up nearby code) - rust-lang#110755 ([LLVM17] Adapt to `ExplicitEmulatedTLS` removal.) - rust-lang#110775 (Update books) - rust-lang#110779 (configure.py: add flag for riscv{64,32}gc musl-root) - rust-lang#110782 (Revert panic oom) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents f6830a2 + 2d72abc commit ed3ddb3

File tree

69 files changed

+1570
-582
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1570
-582
lines changed

compiler/rustc_builtin_macros/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ builtin_macros_requires_cfg_pattern =
44
55
builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
66
7+
builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
8+
79
builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument
810
.label = boolean expression required
911
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use crate::errors;
2+
use crate::util::check_builtin_macro_attribute;
3+
4+
use rustc_ast::ptr::P;
5+
use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind};
6+
use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe};
7+
use rustc_expand::base::{Annotatable, ExtCtxt};
8+
use rustc_span::symbol::{kw, sym, Ident};
9+
use rustc_span::Span;
10+
use thin_vec::{thin_vec, ThinVec};
11+
12+
pub fn expand(
13+
ecx: &mut ExtCtxt<'_>,
14+
_span: Span,
15+
meta_item: &ast::MetaItem,
16+
item: Annotatable,
17+
) -> Vec<Annotatable> {
18+
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
19+
20+
let orig_item = item.clone();
21+
22+
// Allow using `#[alloc_error_handler]` on an item statement
23+
// FIXME - if we get deref patterns, use them to reduce duplication here
24+
let (item, is_stmt, sig_span) =
25+
if let Annotatable::Item(item) = &item
26+
&& let ItemKind::Fn(fn_kind) = &item.kind
27+
{
28+
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
29+
} else if let Annotatable::Stmt(stmt) = &item
30+
&& let StmtKind::Item(item) = &stmt.kind
31+
&& let ItemKind::Fn(fn_kind) = &item.kind
32+
{
33+
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
34+
} else {
35+
ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocErrorMustBeFn {span: item.span() });
36+
return vec![orig_item];
37+
};
38+
39+
// Generate a bunch of new items using the AllocFnFactory
40+
let span = ecx.with_def_site_ctxt(item.span);
41+
42+
// Generate item statements for the allocator methods.
43+
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
44+
45+
// Generate anonymous constant serving as container for the allocator methods.
46+
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
47+
let const_body = ecx.expr_block(ecx.block(span, stmts));
48+
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
49+
let const_item = if is_stmt {
50+
Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
51+
} else {
52+
Annotatable::Item(const_item)
53+
};
54+
55+
// Return the original item and the new methods.
56+
vec![orig_item, const_item]
57+
}
58+
59+
// #[rustc_std_internal_symbol]
60+
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
61+
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
62+
// }
63+
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
64+
let usize = cx.path_ident(span, Ident::new(sym::usize, span));
65+
let ty_usize = cx.ty_path(usize);
66+
let size = Ident::from_str_and_span("size", span);
67+
let align = Ident::from_str_and_span("align", span);
68+
69+
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
70+
let layout_new = cx.expr_path(cx.path(span, layout_new));
71+
let layout = cx.expr_call(
72+
span,
73+
layout_new,
74+
thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
75+
);
76+
77+
let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
78+
79+
let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
80+
let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
81+
let decl = cx.fn_decl(params, never);
82+
let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
83+
let sig = FnSig { decl, header, span: span };
84+
85+
let body = Some(cx.block_expr(call));
86+
let kind = ItemKind::Fn(Box::new(Fn {
87+
defaultness: ast::Defaultness::Final,
88+
sig,
89+
generics: Generics::default(),
90+
body,
91+
}));
92+
93+
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
94+
95+
let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind);
96+
cx.stmt_item(sig_span, item)
97+
}

compiler/rustc_builtin_macros/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ pub(crate) struct OneCfgPattern {
1919
pub(crate) span: Span,
2020
}
2121

22+
#[derive(Diagnostic)]
23+
#[diag(builtin_macros_alloc_error_must_be_fn)]
24+
pub(crate) struct AllocErrorMustBeFn {
25+
#[primary_span]
26+
pub(crate) span: Span,
27+
}
28+
2229
#[derive(Diagnostic)]
2330
#[diag(builtin_macros_assert_requires_boolean)]
2431
pub(crate) struct AssertRequiresBoolean {

compiler/rustc_builtin_macros/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_expand::proc_macro::BangProcMacro;
2727
use rustc_fluent_macro::fluent_messages;
2828
use rustc_span::symbol::sym;
2929

30+
mod alloc_error_handler;
3031
mod assert;
3132
mod cfg;
3233
mod cfg_accessible;
@@ -103,6 +104,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
103104
}
104105

105106
register_attr! {
107+
alloc_error_handler: alloc_error_handler::expand,
106108
bench: test::expand_bench,
107109
cfg_accessible: cfg_accessible::Expander,
108110
cfg_eval: cfg_eval::expand,

compiler/rustc_codegen_cranelift/example/alloc_example.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(start, core_intrinsics)]
1+
#![feature(start, core_intrinsics, alloc_error_handler)]
22
#![no_std]
33

44
extern crate alloc;
@@ -22,6 +22,11 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
2222
core::intrinsics::abort();
2323
}
2424

25+
#[alloc_error_handler]
26+
fn alloc_error_handler(_: alloc::alloc::Layout) -> ! {
27+
core::intrinsics::abort();
28+
}
29+
2530
#[start]
2631
fn main(_argc: isize, _argv: *const *const u8) -> isize {
2732
let world: Box<&str> = Box::new("Hello World!\0");

compiler/rustc_codegen_cranelift/src/allocator.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::prelude::*;
66
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
77
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
88
use rustc_session::config::OomStrategy;
9+
use rustc_span::symbol::sym;
910

1011
/// Returns whether an allocator shim was created
1112
pub(crate) fn codegen(
@@ -14,14 +15,21 @@ pub(crate) fn codegen(
1415
unwind_context: &mut UnwindContext,
1516
) -> bool {
1617
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
17-
codegen_inner(module, unwind_context, kind, tcx.sess.opts.unstable_opts.oom);
18+
codegen_inner(
19+
module,
20+
unwind_context,
21+
kind,
22+
tcx.alloc_error_handler_kind(()).unwrap(),
23+
tcx.sess.opts.unstable_opts.oom,
24+
);
1825
true
1926
}
2027

2128
fn codegen_inner(
2229
module: &mut impl Module,
2330
unwind_context: &mut UnwindContext,
2431
kind: AllocatorKind,
32+
alloc_error_handler_kind: AllocatorKind,
2533
oom_strategy: OomStrategy,
2634
) {
2735
let usize_ty = module.target_config().pointer_type();
@@ -63,6 +71,19 @@ fn codegen_inner(
6371
);
6472
}
6573

74+
let sig = Signature {
75+
call_conv: module.target_config().default_call_conv,
76+
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
77+
returns: vec![],
78+
};
79+
crate::common::create_wrapper_function(
80+
module,
81+
unwind_context,
82+
sig,
83+
"__rust_alloc_error_handler",
84+
&alloc_error_handler_kind.fn_name(sym::oom),
85+
);
86+
6687
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();
6788
let mut data_ctx = DataContext::new();
6889
data_ctx.set_align(1);

compiler/rustc_codegen_gcc/example/alloc_example.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(start, core_intrinsics, lang_items)]
1+
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
22
#![no_std]
33

44
extern crate alloc;
@@ -21,6 +21,11 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
2121
core::intrinsics::abort();
2222
}
2323

24+
#[alloc_error_handler]
25+
fn alloc_error_handler(_: alloc::alloc::Layout) -> ! {
26+
core::intrinsics::abort();
27+
}
28+
2429
#[lang = "eh_personality"]
2530
fn eh_personality() -> ! {
2631
loop {}

compiler/rustc_codegen_gcc/src/allocator.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS
55
use rustc_middle::bug;
66
use rustc_middle::ty::TyCtxt;
77
use rustc_session::config::OomStrategy;
8+
use rustc_span::symbol::sym;
89

910
use crate::GccContext;
1011

11-
pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind) {
12+
pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) {
1213
let context = &mods.context;
1314
let usize =
1415
match tcx.sess.target.pointer_width {
@@ -86,6 +87,37 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
8687
// as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643
8788
}
8889

90+
let types = [usize, usize];
91+
let name = "__rust_alloc_error_handler".to_string();
92+
let args: Vec<_> = types.iter().enumerate()
93+
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
94+
.collect();
95+
let func = context.new_function(None, FunctionType::Exported, void, &args, name, false);
96+
97+
if tcx.sess.target.default_hidden_visibility {
98+
#[cfg(feature="master")]
99+
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
100+
}
101+
102+
let callee = alloc_error_handler_kind.fn_name(sym::oom);
103+
let args: Vec<_> = types.iter().enumerate()
104+
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
105+
.collect();
106+
let callee = context.new_function(None, FunctionType::Extern, void, &args, callee, false);
107+
#[cfg(feature="master")]
108+
callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
109+
110+
let block = func.new_block("entry");
111+
112+
let args = args
113+
.iter()
114+
.enumerate()
115+
.map(|(i, _)| func.get_param(i as i32).to_rvalue())
116+
.collect::<Vec<_>>();
117+
let _ret = context.new_call(None, callee, &args);
118+
//llvm::LLVMSetTailCall(ret, True);
119+
block.end_with_void_return(None);
120+
89121
let name = OomStrategy::SYMBOL.to_string();
90122
let global = context.new_global(None, GlobalKind::Exported, i8, name);
91123
let value = tcx.sess.opts.unstable_opts.oom.should_panic();

compiler/rustc_codegen_gcc/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,11 @@ impl CodegenBackend for GccCodegenBackend {
163163
}
164164

165165
impl ExtraBackendMethods for GccCodegenBackend {
166-
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind) -> Self::Module {
166+
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module {
167167
let mut mods = GccContext {
168168
context: Context::default(),
169169
};
170-
unsafe { allocator::codegen(tcx, &mut mods, module_name, kind); }
170+
unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); }
171171
mods
172172
}
173173

compiler/rustc_codegen_llvm/src/allocator.rs

+48
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS
44
use rustc_middle::bug;
55
use rustc_middle::ty::TyCtxt;
66
use rustc_session::config::{DebugInfo, OomStrategy};
7+
use rustc_span::symbol::sym;
78

89
use crate::debuginfo;
910
use crate::llvm::{self, False, True};
@@ -14,6 +15,7 @@ pub(crate) unsafe fn codegen(
1415
module_llvm: &mut ModuleLlvm,
1516
module_name: &str,
1617
kind: AllocatorKind,
18+
alloc_error_handler_kind: AllocatorKind,
1719
) {
1820
let llcx = &*module_llvm.llcx;
1921
let llmod = module_llvm.llmod();
@@ -98,6 +100,52 @@ pub(crate) unsafe fn codegen(
98100
llvm::LLVMDisposeBuilder(llbuilder);
99101
}
100102

103+
// rust alloc error handler
104+
let args = [usize, usize]; // size, align
105+
106+
let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False);
107+
let name = "__rust_alloc_error_handler";
108+
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
109+
// -> ! DIFlagNoReturn
110+
let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
111+
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
112+
113+
if tcx.sess.target.default_hidden_visibility {
114+
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
115+
}
116+
if tcx.sess.must_emit_unwind_tables() {
117+
let uwtable = attributes::uwtable_attr(llcx);
118+
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
119+
}
120+
121+
let callee = alloc_error_handler_kind.fn_name(sym::oom);
122+
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
123+
// -> ! DIFlagNoReturn
124+
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
125+
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
126+
127+
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
128+
129+
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
130+
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
131+
let args = args
132+
.iter()
133+
.enumerate()
134+
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
135+
.collect::<Vec<_>>();
136+
let ret = llvm::LLVMRustBuildCall(
137+
llbuilder,
138+
ty,
139+
callee,
140+
args.as_ptr(),
141+
args.len() as c_uint,
142+
[].as_ptr(),
143+
0 as c_uint,
144+
);
145+
llvm::LLVMSetTailCall(ret, True);
146+
llvm::LLVMBuildRetVoid(llbuilder);
147+
llvm::LLVMDisposeBuilder(llbuilder);
148+
101149
// __rust_alloc_error_handler_should_panic
102150
let name = OomStrategy::SYMBOL;
103151
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);

compiler/rustc_codegen_llvm/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,11 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
115115
tcx: TyCtxt<'tcx>,
116116
module_name: &str,
117117
kind: AllocatorKind,
118+
alloc_error_handler_kind: AllocatorKind,
118119
) -> ModuleLlvm {
119120
let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
120121
unsafe {
121-
allocator::codegen(tcx, &mut module_llvm, module_name, kind);
122+
allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind);
122123
}
123124
module_llvm
124125
}

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ fn exported_symbols_provider_local(
219219
for symbol_name in ALLOCATOR_METHODS
220220
.iter()
221221
.map(|method| format!("__rust_{}", method.name))
222-
.chain([OomStrategy::SYMBOL.to_string()])
222+
.chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()])
223223
{
224224
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
225225

compiler/rustc_codegen_ssa/src/base.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -635,9 +635,16 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
635635
if let Some(kind) = allocator_kind_for_codegen(tcx) {
636636
let llmod_id =
637637
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
638-
let module_llvm = tcx
639-
.sess
640-
.time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id, kind));
638+
let module_llvm = tcx.sess.time("write_allocator_module", || {
639+
backend.codegen_allocator(
640+
tcx,
641+
&llmod_id,
642+
kind,
643+
// If allocator_kind is Some then alloc_error_handler_kind must
644+
// also be Some.
645+
tcx.alloc_error_handler_kind(()).unwrap(),
646+
)
647+
});
641648

642649
ongoing_codegen.submit_pre_codegened_module_to_llvm(
643650
tcx,

0 commit comments

Comments
 (0)