From 18ac26565f2cb32848da202464d6b69cceb63f74 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 2 May 2014 15:40:07 -0700 Subject: [PATCH] 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 --- src/librustc/middle/reachable.rs | 3 ++- src/test/auxiliary/issue-13620-1.rs | 19 +++++++++++++++++++ src/test/auxiliary/issue-13620-2.rs | 13 +++++++++++++ src/test/run-pass/issue-13620.rs | 18 ++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/test/auxiliary/issue-13620-1.rs create mode 100644 src/test/auxiliary/issue-13620-2.rs create mode 100644 src/test/run-pass/issue-13620.rs diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 6e2edb4e8b2ae..ea4b2c1a71cce 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 0000000000000..ddd1012017f78 --- /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 or the MIT license +// , 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 0000000000000..6ad4a00a352d9 --- /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 or the MIT license +// , 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 0000000000000..13baa80781b00 --- /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 or the MIT license +// , 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)(); +}