Skip to content

Commit 67470be

Browse files
committed
Handle calls to upstream monomorphizations in compiler_builtins
1 parent 1ca424c commit 67470be

File tree

9 files changed

+53
-9
lines changed

9 files changed

+53
-9
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3673,6 +3673,7 @@ dependencies = [
36733673
"rustc_macros",
36743674
"rustc_metadata",
36753675
"rustc_middle",
3676+
"rustc_monomorphize",
36763677
"rustc_query_system",
36773678
"rustc_serialize",
36783679
"rustc_session",

Diff for: compiler/rustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ rustc_index = { path = "../rustc_index" }
2525
rustc_macros = { path = "../rustc_macros" }
2626
rustc_metadata = { path = "../rustc_metadata" }
2727
rustc_middle = { path = "../rustc_middle" }
28+
rustc_monomorphize = { path = "../rustc_monomorphize" }
2829
rustc_query_system = { path = "../rustc_query_system" }
2930
rustc_serialize = { path = "../rustc_serialize" }
3031
rustc_session = { path = "../rustc_session" }

Diff for: compiler/rustc_codegen_ssa/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ codegen_ssa_cgu_not_recorded =
1616
1717
codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
1818
19+
codegen_ssa_compiler_builtins_cannot_call =
20+
`compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call to `{$callee}`
21+
1922
codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error}
2023
2124
codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error}

Diff for: compiler/rustc_codegen_ssa/src/common.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use rustc_hir::LangItem;
44
use rustc_middle::mir;
5+
use rustc_middle::ty::Instance;
56
use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
67
use rustc_span::Span;
78

@@ -120,11 +121,11 @@ pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
120121
bx: &Bx,
121122
span: Option<Span>,
122123
li: LangItem,
123-
) -> (Bx::FnAbiOfResult, Bx::Value) {
124+
) -> (Bx::FnAbiOfResult, Bx::Value, Instance<'tcx>) {
124125
let tcx = bx.tcx();
125126
let def_id = tcx.require_lang_item(li, span);
126127
let instance = ty::Instance::mono(tcx, def_id);
127-
(bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance))
128+
(bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance), instance)
128129
}
129130

130131
// To avoid UB from LLVM, these two functions mask RHS with an

Diff for: compiler/rustc_codegen_ssa/src/errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1030,3 +1030,9 @@ pub struct FailedToGetLayout<'tcx> {
10301030
pub struct ErrorCreatingRemarkDir {
10311031
pub error: std::io::Error,
10321032
}
1033+
1034+
#[derive(Diagnostic)]
1035+
#[diag(codegen_ssa_compiler_builtins_cannot_call)]
1036+
pub struct CompilerBuiltinsCannotCall {
1037+
pub callee: String,
1038+
}

Diff for: compiler/rustc_codegen_ssa/src/mir/block.rs

+34-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::{CachedLlbb, FunctionCx, LocalRef};
55

66
use crate::base;
77
use crate::common::{self, IntPredicate};
8+
use crate::errors::CompilerBuiltinsCannotCall;
89
use crate::meth;
910
use crate::traits::*;
1011
use crate::MemFlags;
@@ -16,7 +17,9 @@ use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTermi
1617
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1718
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
1819
use rustc_middle::ty::{self, Instance, Ty};
20+
use rustc_monomorphize::should_codegen_locally;
1921
use rustc_session::config::OptLevel;
22+
use rustc_span::def_id::LOCAL_CRATE;
2023
use rustc_span::{source_map::Spanned, sym, Span};
2124
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
2225
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
@@ -157,8 +160,27 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
157160
destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>,
158161
mut unwind: mir::UnwindAction,
159162
copied_constant_arguments: &[PlaceRef<'tcx, <Bx as BackendTypes>::Value>],
163+
instance: Option<Instance<'tcx>>,
160164
mergeable_succ: bool,
161165
) -> MergingSucc {
166+
let tcx = bx.tcx();
167+
if let Some(instance) = instance {
168+
if tcx.is_compiler_builtins(LOCAL_CRATE) && !should_codegen_locally(tcx, &instance) {
169+
if destination.is_some() {
170+
let callee = with_no_trimmed_paths!(tcx.def_path_str(instance.def_id()));
171+
tcx.dcx().emit_err(CompilerBuiltinsCannotCall { callee });
172+
} else {
173+
info!(
174+
"compiler_builtins call to diverging function {:?} replaced with abort",
175+
instance.def_id()
176+
);
177+
bx.abort();
178+
bx.unreachable();
179+
return MergingSucc::False;
180+
}
181+
}
182+
}
183+
162184
// If there is a cleanup block and the function we're calling can unwind, then
163185
// do an invoke, otherwise do a call.
164186
let fn_ty = bx.fn_decl_backend_type(fn_abi);
@@ -480,6 +502,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
480502
let ty = location.ty(self.mir, bx.tcx()).ty;
481503
let ty = self.monomorphize(ty);
482504
let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);
505+
let instance = drop_fn.clone();
483506

484507
if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
485508
// we don't actually need to drop anything.
@@ -582,6 +605,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
582605
Some((ReturnDest::Nothing, target)),
583606
unwind,
584607
&[],
608+
Some(instance),
585609
mergeable_succ,
586610
)
587611
}
@@ -658,10 +682,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
658682
}
659683
};
660684

661-
let (fn_abi, llfn) = common::build_langcall(bx, Some(span), lang_item);
685+
let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), lang_item);
662686

663687
// Codegen the actual panic invoke/call.
664-
let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &args, None, unwind, &[], false);
688+
let merging_succ =
689+
helper.do_call(self, bx, fn_abi, llfn, &args, None, unwind, &[], Some(instance), false);
665690
assert_eq!(merging_succ, MergingSucc::False);
666691
MergingSucc::False
667692
}
@@ -677,7 +702,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
677702
self.set_debug_loc(bx, terminator.source_info);
678703

679704
// Obtain the panic entry point.
680-
let (fn_abi, llfn) = common::build_langcall(bx, Some(span), reason.lang_item());
705+
let (fn_abi, llfn, instance) = common::build_langcall(bx, Some(span), reason.lang_item());
681706

682707
// Codegen the actual panic invoke/call.
683708
let merging_succ = helper.do_call(
@@ -689,6 +714,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
689714
None,
690715
mir::UnwindAction::Unreachable,
691716
&[],
717+
Some(instance),
692718
false,
693719
);
694720
assert_eq!(merging_succ, MergingSucc::False);
@@ -738,7 +764,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
738764
let msg = bx.const_str(&msg_str);
739765

740766
// Obtain the panic entry point.
741-
let (fn_abi, llfn) =
767+
let (fn_abi, llfn, instance) =
742768
common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind);
743769

744770
// Codegen the actual panic invoke/call.
@@ -751,6 +777,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
751777
target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)),
752778
unwind,
753779
&[],
780+
Some(instance),
754781
mergeable_succ,
755782
)
756783
} else {
@@ -798,6 +825,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
798825
ty::FnPtr(_) => (None, Some(callee.immediate())),
799826
_ => bug!("{} is not callable", callee.layout.ty),
800827
};
828+
801829
let def = instance.map(|i| i.def);
802830

803831
if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
@@ -1106,6 +1134,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11061134
destination,
11071135
unwind,
11081136
&copied_constant_arguments,
1137+
instance,
11091138
mergeable_succ,
11101139
)
11111140
}
@@ -1664,7 +1693,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16641693

16651694
self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
16661695

1667-
let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, reason.lang_item());
1696+
let (fn_abi, fn_ptr, _instance) = common::build_langcall(&bx, None, reason.lang_item());
16681697
let fn_ty = bx.fn_decl_backend_type(fn_abi);
16691698

16701699
let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref());

Diff for: compiler/rustc_codegen_ssa/src/size_of_val.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
6262
let msg = bx.const_str(&msg_str);
6363

6464
// Obtain the panic entry point.
65-
let (fn_abi, llfn) = common::build_langcall(bx, None, LangItem::PanicNounwind);
65+
let (fn_abi, llfn, _instance) =
66+
common::build_langcall(bx, None, LangItem::PanicNounwind);
6667

6768
// Generate the call.
6869
// Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.

Diff for: compiler/rustc_monomorphize/src/collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ fn visit_instance_use<'tcx>(
10201020

10211021
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
10221022
/// can just link to the upstream crate and therefore don't need a mono item.
1023-
fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
1023+
pub fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
10241024
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
10251025
return true;
10261026
};

Diff for: compiler/rustc_monomorphize/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ mod partitioning;
2020
mod polymorphize;
2121
mod util;
2222

23+
pub use collector::should_codegen_locally;
24+
2325
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
2426

2527
fn custom_coerce_unsize_info<'tcx>(

0 commit comments

Comments
 (0)