diff options
| author | bors <bors@rust-lang.org> | 2024-03-22 16:55:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-22 16:55:11 +0000 |
| commit | b3df0d7e5ef5f7dbeeca3fb289c65680ad013f87 (patch) | |
| tree | 69f2fba7d8cfe5539c5bd785649994250bb5fdd8 /compiler/rustc_monomorphize/src | |
| parent | 1447f9d38ca388ca178a544534b3cff72945fa1e (diff) | |
| parent | 2f6fb234de5a12fd314ec91737c1f3079f023d8c (diff) | |
| download | rust-b3df0d7e5ef5f7dbeeca3fb289c65680ad013f87.tar.gz rust-b3df0d7e5ef5f7dbeeca3fb289c65680ad013f87.zip | |
Auto merge of #122580 - saethlin:compiler-builtins-can-panic, r=pnkfelix
"Handle" calls to upstream monomorphizations in compiler_builtins This is pretty cooked, but I think it works. compiler-builtins has a long-standing problem that at link time, its rlib cannot contain any calls to `core`. And yet, in codegen we _love_ inserting calls to symbols in `core`, generally from various panic entrypoints. I intend this PR to attack that problem as completely as possible. When we generate a function call, we now check if we are generating a function call from `compiler_builtins` and whether the callee is a function which was not lowered in the current crate, meaning we will have to link to it. If those conditions are met, actually generating the call is asking for a linker error. So we don't. If the callee diverges, we lower to an abort with the same behavior as `core::intrinsics::abort`. If the callee does not diverge, we produce an error. This means that compiler-builtins can contain panics, but they'll SIGILL instead of panicking. I made non-diverging calls a compile error because I'm guessing that they'd mostly get into compiler-builtins by someone making a mistake while working on the crate, and compile errors are better than linker errors. We could turn such calls into aborts as well if that's preferred.
Diffstat (limited to 'compiler/rustc_monomorphize/src')
| -rw-r--r-- | compiler/rustc_monomorphize/src/collector.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/lib.rs | 22 |
2 files changed, 23 insertions, 1 deletions
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1a18a84b358..673cd968e28 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1107,7 +1107,7 @@ fn visit_instance_use<'tcx>( /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. -fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool { +pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool { let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else { return true; }; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 7f36ae91f1a..4ec842e8f85 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -11,7 +11,10 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::query::{Providers, TyCtxtAt}; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; +use rustc_middle::ty::Instance; +use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{self, Ty}; +use rustc_span::def_id::LOCAL_CRATE; use rustc_span::ErrorGuaranteed; mod collector; @@ -20,6 +23,8 @@ mod partitioning; mod polymorphize; mod util; +use collector::should_codegen_locally; + rustc_fluent_macro::fluent_messages! { "../messages.ftl" } fn custom_coerce_unsize_info<'tcx>( @@ -45,6 +50,23 @@ fn custom_coerce_unsize_info<'tcx>( } } +/// Returns whether a call from the current crate to the [`Instance`] would produce a call +/// from `compiler_builtins` to a symbol the linker must resolve. +/// +/// Such calls from `compiler_bultins` are effectively impossible for the linker to handle. Some +/// linkers will optimize such that dead calls to unresolved symbols are not an error, but this is +/// not guaranteed. So we used this function in codegen backends to ensure we do not generate any +/// unlinkable calls. +pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>( + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, +) -> bool { + !instance.def_id().is_local() + && tcx.is_compiler_builtins(LOCAL_CRATE) + && tcx.codegen_fn_attrs(instance.def_id()).link_name.is_none() + && !should_codegen_locally(tcx, &instance) +} + pub fn provide(providers: &mut Providers) { partitioning::provide(providers); polymorphize::provide(providers); |
