From ee810a75e41368387918759ed191657f05650f05 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Tue, 9 Jun 2020 15:49:59 +0100 Subject: [PATCH] Fix exports with `#[inline(always)]` --- src/librustc_middle/mir/mono.rs | 15 +++++-------- .../codegen/cdylib-external-inline-fns.rs | 20 ++++++++++++++++++ src/test/codegen/export-no-mangle.rs | 21 ++++++++++++------- src/test/codegen/external-no-mangle-fns.rs | 10 +++++++++ .../codegen/staticlib-external-inline-fns.rs | 20 ++++++++++++++++++ 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() {}