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.
This commit is contained in:
commit
9057355f50
@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
use cranelift_codegen::ir::SigRef;
|
use cranelift_codegen::ir::SigRef;
|
||||||
use cranelift_module::ModuleError;
|
use cranelift_module::ModuleError;
|
||||||
|
use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::ty::layout::FnAbiOf;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
|
use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_target::abi::call::{Conv, FnAbi};
|
use rustc_target::abi::call::{Conv, FnAbi};
|
||||||
@ -372,6 +375,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
|||||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
|
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
|
||||||
.polymorphize(fx.tcx);
|
.polymorphize(fx.tcx);
|
||||||
|
|
||||||
|
if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) {
|
||||||
|
if target.is_some() {
|
||||||
|
let caller = with_no_trimmed_paths!(fx.tcx.def_path_str(fx.instance.def_id()));
|
||||||
|
let callee = with_no_trimmed_paths!(fx.tcx.def_path_str(def_id));
|
||||||
|
fx.tcx.dcx().emit_err(CompilerBuiltinsCannotCall { caller, callee });
|
||||||
|
} else {
|
||||||
|
fx.bcx.ins().trap(TrapCode::User(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
|
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
|
||||||
crate::intrinsics::codegen_llvm_intrinsic_call(
|
crate::intrinsics::codegen_llvm_intrinsic_call(
|
||||||
fx,
|
fx,
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::layout::FnAbiOf;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
|
use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization;
|
||||||
|
|
||||||
use crate::constant::ConstantCx;
|
use crate::constant::ConstantCx;
|
||||||
use crate::debuginfo::FunctionDebugContext;
|
use crate::debuginfo::FunctionDebugContext;
|
||||||
@ -999,6 +1000,12 @@ fn codegen_panic_inner<'tcx>(
|
|||||||
let def_id = fx.tcx.require_lang_item(lang_item, span);
|
let def_id = fx.tcx.require_lang_item(lang_item, span);
|
||||||
|
|
||||||
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
|
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
|
||||||
|
|
||||||
|
if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) {
|
||||||
|
fx.bcx.ins().trap(TrapCode::User(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let symbol_name = fx.tcx.symbol_name(instance).name;
|
let symbol_name = fx.tcx.symbol_name(instance).name;
|
||||||
|
|
||||||
fx.lib_call(
|
fx.lib_call(
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
extern crate rustc_incremental;
|
extern crate rustc_incremental;
|
||||||
extern crate rustc_index;
|
extern crate rustc_index;
|
||||||
extern crate rustc_metadata;
|
extern crate rustc_metadata;
|
||||||
|
extern crate rustc_monomorphize;
|
||||||
extern crate rustc_session;
|
extern crate rustc_session;
|
||||||
extern crate rustc_span;
|
extern crate rustc_span;
|
||||||
extern crate rustc_target;
|
extern crate rustc_target;
|
||||||
|
Loading…
Reference in New Issue
Block a user