Export `#[inline] #[no_mangle]` fns in cdylibs and staticlibs
This commit is contained in:
parent
ce6d3a73b5
commit
f62903b74a
|
@ -89,10 +89,11 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
|||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
|
||||
let def_id = tcx.hir().local_def_id(hir_id);
|
||||
let generics = tcx.generics_of(def_id);
|
||||
if !generics.requires_monomorphization(tcx) &&
|
||||
// Functions marked with #[inline] are only ever codegened
|
||||
// with "internal" linkage and are never exported.
|
||||
!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx)
|
||||
if !generics.requires_monomorphization(tcx)
|
||||
&& (!Instance::mono(tcx, def_id.to_def_id())
|
||||
.def
|
||||
.generates_cgu_internal_copy(tcx)
|
||||
|| tcx.inline_exportable(def_id.to_def_id()))
|
||||
{
|
||||
Some(def_id)
|
||||
} else {
|
||||
|
|
|
@ -95,6 +95,7 @@ impl<'tcx> MonoItem<'tcx> {
|
|||
// linkage, then we'll be creating a globally shared version.
|
||||
if self.explicit_linkage(tcx).is_some()
|
||||
|| !instance.def.generates_cgu_internal_copy(tcx)
|
||||
|| tcx.inline_exportable(instance.def_id())
|
||||
|| Some(instance.def_id()) == entry_def_id.map(LocalDefId::to_def_id)
|
||||
{
|
||||
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||
|
|
|
@ -697,6 +697,10 @@ rustc_queries! {
|
|||
storage(ArenaCacheSelector<'tcx>)
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
|
||||
query inline_exportable(def_id: DefId) -> bool {
|
||||
desc { |tcx| "computing whether `{}` should be explicitly exported", tcx.def_path_str(def_id) }
|
||||
}
|
||||
}
|
||||
|
||||
Other {
|
||||
|
|
|
@ -40,6 +40,7 @@ use rustc_middle::ty::util::Discr;
|
|||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::lint;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
|
@ -79,6 +80,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
|||
static_mutability,
|
||||
generator_kind,
|
||||
codegen_fn_attrs,
|
||||
inline_exportable,
|
||||
collect_mod_item_types,
|
||||
..*providers
|
||||
};
|
||||
|
@ -2599,6 +2601,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
|
|||
codegen_fn_attrs
|
||||
}
|
||||
|
||||
fn inline_exportable(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
// Functions marked with #[inline] are only ever codegened
|
||||
// with "internal" linkage and are never exported unless we're
|
||||
// building a `staticlib` or `cdylib` and they are marked
|
||||
// `#[no_mangle]`.
|
||||
tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|
||||
&& (tcx.sess.crate_types().contains(&CrateType::Cdylib)
|
||||
|| tcx.sess.crate_types().contains(&CrateType::Staticlib))
|
||||
}
|
||||
|
||||
/// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
|
||||
/// applied to the method prototype.
|
||||
fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
|
||||
#![crate_type = "cdylib"]
|
||||
|
||||
// CHECK: define void @a()
|
||||
#[no_mangle]
|
||||
#[inline]
|
||||
pub extern "C" fn a() {
|
||||
// side effect to keep `a` around
|
||||
unsafe {
|
||||
core::ptr::read_volatile(&42);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
|
||||
#![crate_type = "staticlib"]
|
||||
|
||||
// CHECK: define void @a()
|
||||
#[no_mangle]
|
||||
#[inline]
|
||||
pub extern "C" fn a() {
|
||||
// side effect to keep `a` around
|
||||
unsafe {
|
||||
core::ptr::read_volatile(&42);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue