about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathan Corbyn <me@nathancorbyn.com>2020-06-09 15:49:59 +0100
committerNathan Corbyn <me@nathancorbyn.com>2020-06-15 09:40:56 +0100
commitee810a75e41368387918759ed191657f05650f05 (patch)
tree94cb432f7a4afaefc451bcde7a506bfc8918b765
parentd23bedd13d70597a7db70ef5ea549fc7a4063d10 (diff)
downloadrust-ee810a75e41368387918759ed191657f05650f05.tar.gz
rust-ee810a75e41368387918759ed191657f05650f05.zip
Fix exports with `#[inline(always)]`
-rw-r--r--src/librustc_middle/mir/mono.rs15
-rw-r--r--src/test/codegen/cdylib-external-inline-fns.rs20
-rw-r--r--src/test/codegen/export-no-mangle.rs21
-rw-r--r--src/test/codegen/external-no-mangle-fns.rs10
-rw-r--r--src/test/codegen/staticlib-external-inline-fns.rs20
5 files changed, 68 insertions, 18 deletions
diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs
index 886690da212..24d324ff09c 100644
--- a/src/librustc_middle/mir/mono.rs
+++ b/src/librustc_middle/mir/mono.rs
@@ -91,10 +91,9 @@ impl<'tcx> MonoItem<'tcx> {
         match *self {
             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 or an extern indicator, then we'll be creating a
-                // globally shared version.
-                if self.explicit_linkage(tcx).is_some()
+                // If this function isn't inlined or otherwise has an extern
+                // indicator, then we'll be creating a globally shared version.
+                if tcx.codegen_fn_attrs(instance.def_id()).contains_extern_indicator()
                     || !instance.def.generates_cgu_internal_copy(tcx)
                     || Some(instance.def_id()) == entry_def_id.map(LocalDefId::to_def_id)
                 {
@@ -103,12 +102,8 @@ 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. 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()
-                {
+                // be creating a local copy per CGU. 
+                if generate_cgu_internal_copies {
                     return InstantiationMode::LocalCopy;
                 }
 
diff --git a/src/test/codegen/cdylib-external-inline-fns.rs b/src/test/codegen/cdylib-external-inline-fns.rs
index 58f806b5a1f..519be6b6a99 100644
--- a/src/test/codegen/cdylib-external-inline-fns.rs
+++ b/src/test/codegen/cdylib-external-inline-fns.rs
@@ -21,3 +21,23 @@ extern "C" fn c() {}
 #[export_name = "d"]
 #[inline]
 extern "C" fn d() {}
+
+// CHECK: define void @e()
+#[no_mangle]
+#[inline(always)]
+pub extern "C" fn e() {}
+
+// CHECK: define void @f()
+#[export_name = "f"]
+#[inline(always)]
+pub extern "C" fn f() {}
+
+// CHECK: define void @g()
+#[no_mangle]
+#[inline(always)]
+extern "C" fn g() {}
+
+// CHECK: define void @h()
+#[export_name = "h"]
+#[inline(always)]
+extern "C" fn h() {}
diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs
index a52fac37021..11427ae3882 100644
--- a/src/test/codegen/export-no-mangle.rs
+++ b/src/test/codegen/export-no-mangle.rs
@@ -11,16 +11,21 @@ mod private {
     #[export_name = "BAR"]
     static BAR: u32 = 3;
 
-    // CHECK: void @foo()
+    // CHECK: void @a()
     #[no_mangle]
-    pub extern fn foo() {}
+    pub extern fn a() {}
 
-    // CHECK: void @bar()
-    #[export_name = "bar"]
-    extern fn bar() {}
+    // CHECK: void @b()
+    #[export_name = "b"]
+    extern fn b() {}
 
-    // CHECK: void @baz()
-    #[export_name = "baz"]
+    // CHECK: void @c()
+    #[export_name = "c"]
     #[inline]
-    extern fn baz() {}
+    extern fn c() {}
+    
+    // CHECK: void @d()
+    #[export_name = "d"]
+    #[inline(always)]
+    extern fn d() {}
 }
diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs
index aefa9ce21c3..41820b057f1 100644
--- a/src/test/codegen/external-no-mangle-fns.rs
+++ b/src/test/codegen/external-no-mangle-fns.rs
@@ -63,3 +63,13 @@ fn i() {}
 #[no_mangle]
 #[inline]
 pub fn j() {}
+
+// CHECK: define void @k()
+#[no_mangle]
+#[inline(always)]
+fn k() {}
+
+// CHECK: define void @l()
+#[no_mangle]
+#[inline(always)]
+pub fn l() {}
diff --git a/src/test/codegen/staticlib-external-inline-fns.rs b/src/test/codegen/staticlib-external-inline-fns.rs
index 8f55a530331..8876ab7376a 100644
--- a/src/test/codegen/staticlib-external-inline-fns.rs
+++ b/src/test/codegen/staticlib-external-inline-fns.rs
@@ -21,3 +21,23 @@ extern "C" fn c() {}
 #[export_name = "d"]
 #[inline]
 extern "C" fn d() {}
+
+// CHECK: define void @e()
+#[no_mangle]
+#[inline(always)]
+pub extern "C" fn e() {}
+
+// CHECK: define void @f()
+#[export_name = "f"]
+#[inline(always)]
+pub extern "C" fn f() {}
+
+// CHECK: define void @g()
+#[no_mangle]
+#[inline(always)]
+extern "C" fn g() {}
+
+// CHECK: define void @h()
+#[export_name = "h"]
+#[inline(always)]
+extern "C" fn h() {}