about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-05-02 15:40:07 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-05-02 15:40:07 -0700
commit18ac26565f2cb32848da202464d6b69cceb63f74 (patch)
tree9bcfc78818d0d4ded905b0e5fc1dc4693efd2b8e
parentb5d6b07370b665df6b54fa20e971e61041a233b0 (diff)
downloadrust-18ac26565f2cb32848da202464d6b69cceb63f74.tar.gz
rust-18ac26565f2cb32848da202464d6b69cceb63f74.zip
rustc: Crawl static initializers for reachability
This ensures that private functions exported through static initializers will
actually end up being public in the object file (so other objects can continue
to reference the function).

Closes #13620
-rw-r--r--src/librustc/middle/reachable.rs3
-rw-r--r--src/test/auxiliary/issue-13620-1.rs19
-rw-r--r--src/test/auxiliary/issue-13620-2.rs13
-rw-r--r--src/test/run-pass/issue-13620.rs18
4 files changed, 52 insertions, 1 deletions
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 6e2edb4e8b2..ea4b2c1a71c 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -270,11 +270,12 @@ impl<'a> ReachableContext<'a> {
 
                     // Statics with insignificant addresses are not reachable
                     // because they're inlined specially into all other crates.
-                    ast::ItemStatic(..) => {
+                    ast::ItemStatic(_, _, init) => {
                         if attr::contains_name(item.attrs.as_slice(),
                                                "address_insignificant") {
                             self.reachable_symbols.remove(&search_item);
                         }
+                        visit::walk_expr(self, init, ());
                     }
 
                     // These are normal, nothing reachable about these
diff --git a/src/test/auxiliary/issue-13620-1.rs b/src/test/auxiliary/issue-13620-1.rs
new file mode 100644
index 00000000000..ddd1012017f
--- /dev/null
+++ b/src/test/auxiliary/issue-13620-1.rs
@@ -0,0 +1,19 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Foo {
+    pub foo: extern fn()
+}
+
+extern fn the_foo() {}
+
+pub static FOO: Foo = Foo {
+    foo: the_foo
+};
diff --git a/src/test/auxiliary/issue-13620-2.rs b/src/test/auxiliary/issue-13620-2.rs
new file mode 100644
index 00000000000..6ad4a00a352
--- /dev/null
+++ b/src/test/auxiliary/issue-13620-2.rs
@@ -0,0 +1,13 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate crate1 = "issue-13620-1";
+
+pub static FOO2: crate1::Foo = crate1::FOO;
diff --git a/src/test/run-pass/issue-13620.rs b/src/test/run-pass/issue-13620.rs
new file mode 100644
index 00000000000..13baa80781b
--- /dev/null
+++ b/src/test/run-pass/issue-13620.rs
@@ -0,0 +1,18 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue-13620-1.rs
+// aux-build:issue-13620-2.rs
+
+extern crate crate2 = "issue-13620-2";
+
+fn main() {
+    (crate2::FOO2.foo)();
+}