about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathan Corbyn <me@nathancorbyn.com>2020-06-08 09:37:11 +0100
committerNathan Corbyn <me@nathancorbyn.com>2020-06-15 09:40:56 +0100
commit6b7cacb2c99567a76cf0d5ce6833a129c8bb8814 (patch)
treef0a358cb6e0cb9ea6a0aeedc366b00dd66b3a4a9
parentf62903b74a8630fa62e721f69e6621d1d441e7f1 (diff)
downloadrust-6b7cacb2c99567a76cf0d5ce6833a129c8bb8814.tar.gz
rust-6b7cacb2c99567a76cf0d5ce6833a129c8bb8814.zip
Export all fns with extern indicator
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs9
-rw-r--r--src/librustc_middle/mir/mono.rs12
-rw-r--r--src/librustc_middle/query/mod.rs4
-rw-r--r--src/librustc_typeck/collect.rs12
-rw-r--r--src/test/codegen/cdylib-external-inline-fns.rs23
-rw-r--r--src/test/codegen/cdylib-external-no-mangle-fns.rs13
-rw-r--r--src/test/codegen/export-no-mangle.rs5
-rw-r--r--src/test/codegen/external-no-mangle-fns.rs10
-rw-r--r--src/test/codegen/staticlib-external-inline-fns.rs23
-rw-r--r--src/test/codegen/staticlib-external-no-mangle-fns.rs13
10 files changed, 74 insertions, 50 deletions
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index bf8693f3547..98f7da8361c 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -90,10 +90,11 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
                     let def_id = tcx.hir().local_def_id(hir_id);
                     let generics = tcx.generics_of(def_id);
                     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()))
+                        // Functions marked with #[inline] are codegened with "internal"
+                        // linkage and are not exported unless marked with an extern
+                        // inidicator
+                        && (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx)
+                            || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator())
                     {
                         Some(def_id)
                     } else {
diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs
index d8dcf0dea8a..886690da212 100644
--- a/src/librustc_middle/mir/mono.rs
+++ b/src/librustc_middle/mir/mono.rs
@@ -92,10 +92,10 @@ impl<'tcx> MonoItem<'tcx> {
             MonoItem::Fn(ref instance) => {
                 let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id);
                 // If this function isn't inlined or otherwise has explicit
-                // linkage, then we'll be creating a globally shared version.
+                // linkage or an extern indicator, 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 };
@@ -103,8 +103,12 @@ impl<'tcx> MonoItem<'tcx> {
 
                 // At this point we don't have explicit linkage and we're an
                 // inlined function. If we're inlining into all CGUs then we'll
-                // be creating a local copy per CGU
-                if generate_cgu_internal_copies {
+                // be creating a local copy per CGU. We need to watch out here
+                // for an extern indicator as we don't want to optimise away
+                // inlined functions that should be exported.
+                if generate_cgu_internal_copies
+                    && !tcx.codegen_fn_attrs(instance.def_id()).contains_extern_indicator()
+                {
                     return InstantiationMode::LocalCopy;
                 }
 
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index 20487fdb669..be15e6c576f 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -697,10 +697,6 @@ 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 08a6330e718..1d59d749634 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -40,7 +40,6 @@ 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};
@@ -80,7 +79,6 @@ pub fn provide(providers: &mut Providers<'_>) {
         static_mutability,
         generator_kind,
         codegen_fn_attrs,
-        inline_exportable,
         collect_mod_item_types,
         ..*providers
     };
@@ -2601,16 +2599,6 @@ 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-inline-fns.rs b/src/test/codegen/cdylib-external-inline-fns.rs
new file mode 100644
index 00000000000..58f806b5a1f
--- /dev/null
+++ b/src/test/codegen/cdylib-external-inline-fns.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "cdylib"]
+
+// CHECK: define void @a()
+#[no_mangle]
+#[inline]
+pub extern "C" fn a() {}
+
+// CHECK: define void @b()
+#[export_name = "b"]
+#[inline]
+pub extern "C" fn b() {}
+
+// CHECK: define void @c()
+#[no_mangle]
+#[inline]
+extern "C" fn c() {}
+
+// CHECK: define void @d()
+#[export_name = "d"]
+#[inline]
+extern "C" fn d() {}
diff --git a/src/test/codegen/cdylib-external-no-mangle-fns.rs b/src/test/codegen/cdylib-external-no-mangle-fns.rs
deleted file mode 100644
index 827de7e5c11..00000000000
--- a/src/test/codegen/cdylib-external-no-mangle-fns.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs
index 78d41e4be0a..793636bb1b0 100644
--- a/src/test/codegen/export-no-mangle.rs
+++ b/src/test/codegen/export-no-mangle.rs
@@ -18,4 +18,9 @@ mod private {
     // CHECK: void @bar()
     #[export_name = "bar"]
     extern fn bar() {}
+    
+    // CHECK: void @baz()
+    #[export_name = "baz"]
+    #[inline]
+    extern fn baz() {}
 }
diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs
index 90288214499..aefa9ce21c3 100644
--- a/src/test/codegen/external-no-mangle-fns.rs
+++ b/src/test/codegen/external-no-mangle-fns.rs
@@ -53,3 +53,13 @@ fn x() {
         core::ptr::read_volatile(&42);
     }
 }
+
+// CHECK: define void @i()
+#[no_mangle]
+#[inline]
+fn i() {}
+
+// CHECK: define void @j()
+#[no_mangle]
+#[inline]
+pub fn j() {}
diff --git a/src/test/codegen/staticlib-external-inline-fns.rs b/src/test/codegen/staticlib-external-inline-fns.rs
new file mode 100644
index 00000000000..8f55a530331
--- /dev/null
+++ b/src/test/codegen/staticlib-external-inline-fns.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "staticlib"]
+
+// CHECK: define void @a()
+#[no_mangle]
+#[inline]
+pub extern "C" fn a() {}
+
+// CHECK: define void @b()
+#[export_name = "b"]
+#[inline]
+pub extern "C" fn b() {}
+
+// CHECK: define void @c()
+#[no_mangle]
+#[inline]
+extern "C" fn c() {}
+
+// CHECK: define void @d()
+#[export_name = "d"]
+#[inline]
+extern "C" fn d() {}
diff --git a/src/test/codegen/staticlib-external-no-mangle-fns.rs b/src/test/codegen/staticlib-external-no-mangle-fns.rs
deleted file mode 100644
index 0b4a37febb2..00000000000
--- a/src/test/codegen/staticlib-external-no-mangle-fns.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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);
-    }
-}