diff options
| author | Nathan Corbyn <me@nathancorbyn.com> | 2020-06-05 16:47:37 +0100 |
|---|---|---|
| committer | Nathan Corbyn <me@nathancorbyn.com> | 2020-06-15 09:40:56 +0100 |
| commit | f62903b74a8630fa62e721f69e6621d1d441e7f1 (patch) | |
| tree | a054cf5352766f8084835cc3f9326a316f83cd96 /src | |
| parent | ce6d3a73b514e9649e57cee812ad129bb2112016 (diff) | |
| download | rust-f62903b74a8630fa62e721f69e6621d1d441e7f1.tar.gz rust-f62903b74a8630fa62e721f69e6621d1d441e7f1.zip | |
Export `#[inline] #[no_mangle]` fns in cdylibs and staticlibs
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_codegen_ssa/back/symbol_export.rs | 9 | ||||
| -rw-r--r-- | src/librustc_middle/mir/mono.rs | 1 | ||||
| -rw-r--r-- | src/librustc_middle/query/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 12 | ||||
| -rw-r--r-- | src/test/codegen/cdylib-external-no-mangle-fns.rs | 13 | ||||
| -rw-r--r-- | src/test/codegen/staticlib-external-no-mangle-fns.rs | 13 |
6 files changed, 48 insertions, 4 deletions
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 970d13b30c0..bf8693f3547 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -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 { diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index c889dbc0a44..d8dcf0dea8a 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -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 }; diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index be15e6c576f..20487fdb669 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -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 { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1d59d749634..08a6330e718 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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 { diff --git a/src/test/codegen/cdylib-external-no-mangle-fns.rs b/src/test/codegen/cdylib-external-no-mangle-fns.rs new file mode 100644 index 00000000000..827de7e5c11 --- /dev/null +++ b/src/test/codegen/cdylib-external-no-mangle-fns.rs @@ -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); + } +} diff --git a/src/test/codegen/staticlib-external-no-mangle-fns.rs b/src/test/codegen/staticlib-external-no-mangle-fns.rs new file mode 100644 index 00000000000..0b4a37febb2 --- /dev/null +++ b/src/test/codegen/staticlib-external-no-mangle-fns.rs @@ -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); + } +} |
