diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 54eb2dc9e2890..7eab37cb972d6 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -127,6 +127,8 @@ impl CodegenFnAttrs { /// * `#[linkage]` is present pub fn contains_extern_indicator(&self) -> bool { self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + || self.flags.contains(CodegenFnAttrFlags::USED) + || self.flags.contains(CodegenFnAttrFlags::USED_LINKER) || self.export_name.is_some() || match self.linkage { // These are private, so make sure we don't try to consider diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index c777074df4641..8617b61bad28a 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -11,7 +11,6 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::{Node, PatKind, TyKind}; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; @@ -466,10 +465,7 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { // #[used], #[no_mangle], #[export_name], etc also keeps the item alive // forcefully, e.g., for placing it in a specific section. - if cg_attrs.contains_extern_indicator() - || cg_attrs.flags.contains(CodegenFnAttrFlags::USED) - || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) - { + if cg_attrs.contains_extern_indicator() { return true; } diff --git a/src/test/codegen/external-used-statics.rs b/src/test/codegen/external-used-statics.rs new file mode 100644 index 0000000000000..eda08504d086f --- /dev/null +++ b/src/test/codegen/external-used-statics.rs @@ -0,0 +1,78 @@ +// revisions: lib staticlib +// ignore-emscripten default visibility is hidden +// compile-flags: -O +// `#[used]`d static variables always have external linkage, i.e., no `internal` in their +// definitions + +#![cfg_attr(lib, crate_type = "lib")] +#![cfg_attr(staticlib, crate_type = "staticlib")] + +// CHECK: @{{.*}}A{{.*}} = constant +#[used] +static A: u8 = 0; + +// CHECK: @{{.*}}B{{.*}} = global +#[used] +static mut B: u8 = 0; + +// CHECK: @{{.*}}C{{.*}} = constant +#[used] +pub static C: u8 = 0; + +// CHECK: @{{.*}}D{{.*}} = global +#[used] +pub static mut D: u8 = 0; + +mod private { + // CHECK: @{{.*}}E{{.*}} = constant + #[used] + static E: u8 = 0; + + // CHECK: @{{.*}}F{{.*}} = global + #[used] + static mut F: u8 = 0; + + // CHECK: @{{.*}}G{{.*}} = constant + #[used] + pub static G: u8 = 0; + + // CHECK: @{{.*}}H{{.*}} = global + #[used] + pub static mut H: u8 = 0; +} + +const HIDDEN: () = { + // CHECK: @{{.*}}I{{.*}} = constant + #[used] + static I: u8 = 0; + + // CHECK: @{{.*}}J{{.*}} = global + #[used] + static mut J: u8 = 0; + + // CHECK: @{{.*}}K{{.*}} = constant + #[used] + pub static K: u8 = 0; + + // CHECK: @{{.*}}L{{.*}} = global + #[used] + pub static mut L: u8 = 0; +}; + +fn x() { + // CHECK: @{{.*}}M{{.*}} = constant + #[used] + static M: fn() = x; + + // CHECK: @{{.*}}N{{.*}} = global + #[used] + static mut N: u8 = 0; + + // CHECK: @{{.*}}O{{.*}} = constant + #[used] + pub static O: u8 = 0; + + // CHECK: @{{.*}}P{{.*}} = global + #[used] + pub static mut P: u8 = 0; +}