about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2021-04-25 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2021-04-25 00:00:00 +0000
commiteaddc8febd02ca0b0cbd0fa08b8b752cb347b725 (patch)
tree27af9529b537286e91ee3b34195e8d86b6ad21c3
parent13a2615883aa28433383a723a764ca9acb43fd48 (diff)
downloadrust-eaddc8febd02ca0b0cbd0fa08b8b752cb347b725.tar.gz
rust-eaddc8febd02ca0b0cbd0fa08b8b752cb347b725.zip
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.
-rw-r--r--compiler/rustc_passes/src/reachable.rs3
-rw-r--r--src/test/codegen/external-no-mangle-statics.rs4
-rw-r--r--src/test/ui/cross-crate/auxiliary/static_init_aux.rs10
-rw-r--r--src/test/ui/cross-crate/static-init.rs15
4 files changed, 26 insertions, 6 deletions
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 20aaaea5b98..ec47f597257 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 ee61814678c..feb4af6286e 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 00000000000..3b664f43654
--- /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 00000000000..2e893c5d9bf
--- /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();
+}