From eaddc8febd02ca0b0cbd0fa08b8b752cb347b725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 25 Apr 2021 00:00:00 +0000 Subject: [PATCH] Reachable statics have reachable initializers Static initializer can read other statics. Initializers are evaluated at compile time, and so their content could become inlined into another crate. Ensure that initializers of reachable statics are also reachable. Previously, when an item incorrectly considered to be unreachable was reached from another crate an attempt would be made to codegen it. The attempt could fail with an ICE (in the case MIR wasn't available to do so) in some circumstances the attempt could also succeed resulting in a local codegen of non-local items, including static ones. --- compiler/rustc_passes/src/reachable.rs | 3 +-- src/test/codegen/external-no-mangle-statics.rs | 4 ---- .../ui/cross-crate/auxiliary/static_init_aux.rs | 10 ++++++++++ src/test/ui/cross-crate/static-init.rs | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/cross-crate/auxiliary/static_init_aux.rs create mode 100644 src/test/ui/cross-crate/static-init.rs diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 20aaaea5b9809..ec47f5972573d 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -250,7 +250,7 @@ impl<'tcx> ReachableContext<'tcx> { // Reachable constants will be inlined into other crates // unconditionally, so we need to make sure that their // contents are also reachable. - hir::ItemKind::Const(_, init) => { + hir::ItemKind::Const(_, init) | hir::ItemKind::Static(_, _, init) => { self.visit_nested_body(init); } @@ -261,7 +261,6 @@ impl<'tcx> ReachableContext<'tcx> { | hir::ItemKind::Use(..) | hir::ItemKind::OpaqueTy(..) | hir::ItemKind::TyAlias(..) - | hir::ItemKind::Static(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Impl { .. } diff --git a/src/test/codegen/external-no-mangle-statics.rs b/src/test/codegen/external-no-mangle-statics.rs index ee61814678ce4..feb4af6286eea 100644 --- a/src/test/codegen/external-no-mangle-statics.rs +++ b/src/test/codegen/external-no-mangle-statics.rs @@ -58,7 +58,6 @@ const HIDDEN: () = { pub static mut L: u8 = 0; }; -// The surrounding item should not accidentally become external fn x() { // CHECK: @M = local_unnamed_addr constant #[no_mangle] @@ -76,6 +75,3 @@ fn x() { #[no_mangle] pub static mut P: u8 = 0; } -// CHECK-LABEL: ; external_no_mangle_statics::x -// CHECK-NEXT: ; Function Attrs: -// CHECK-NEXT: define internal diff --git a/src/test/ui/cross-crate/auxiliary/static_init_aux.rs b/src/test/ui/cross-crate/auxiliary/static_init_aux.rs new file mode 100644 index 0000000000000..3b664f43654e9 --- /dev/null +++ b/src/test/ui/cross-crate/auxiliary/static_init_aux.rs @@ -0,0 +1,10 @@ +pub static V: &u32 = &X; +pub static F: fn() = f; + +static X: u32 = 42; + +pub fn v() -> *const u32 { + V +} + +fn f() {} diff --git a/src/test/ui/cross-crate/static-init.rs b/src/test/ui/cross-crate/static-init.rs new file mode 100644 index 0000000000000..2e893c5d9bff9 --- /dev/null +++ b/src/test/ui/cross-crate/static-init.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:static_init_aux.rs +extern crate static_init_aux as aux; + +static V: &u32 = aux::V; +static F: fn() = aux::F; + +fn v() -> *const u32 { + V +} + +fn main() { + assert_eq!(aux::v(), crate::v()); + F(); +}