diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index a6cd431c603..85d702d577e 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -128,11 +128,28 @@ impl Visitor<()> for MarkSymbolVisitor { }; let def_id = def_id_of_def(def); - if ReachableContext:: - def_id_represents_local_inlined_item(self.tcx, def_id) { - self.worklist.push(def_id.node) + if is_local(def_id) { + if ReachableContext:: + def_id_represents_local_inlined_item(self.tcx, def_id) { + self.worklist.push(def_id.node) + } else { + match def { + // If this path leads to a static, then we may have + // to do some work to figure out whether the static + // is indeed reachable (address_insignificant + // statics are *never* reachable). + ast::DefStatic(..) => { + self.worklist.push(def_id.node); + } + + // If this wasn't a static, then this destination is + // surely reachable. + _ => { + self.reachable_symbols.insert(def_id.node); + } + } } - self.reachable_symbols.insert(def_id.node); + } } ast::ExprMethodCall(..) => { match self.method_map.find(&expr.id) { @@ -140,13 +157,15 @@ impl Visitor<()> for MarkSymbolVisitor { origin: typeck::method_static(def_id), .. }) => { - if ReachableContext:: - def_id_represents_local_inlined_item( - self.tcx, - def_id) { - self.worklist.push(def_id.node) - } - self.reachable_symbols.insert(def_id.node); + if is_local(def_id) { + if ReachableContext:: + def_id_represents_local_inlined_item( + self.tcx, + def_id) { + self.worklist.push(def_id.node) + } + self.reachable_symbols.insert(def_id.node); + } } Some(_) => {} None => { @@ -310,10 +329,19 @@ impl ReachableContext { } } + // Statics with insignificant addresses are not reachable + // because they're inlined specially into all other crates. + ast::item_static(..) => { + if attr::contains_name(item.attrs, + "address_insignificant") { + self.reachable_symbols.remove(&search_item); + } + } + // These are normal, nothing reachable about these // inherently and their children are already in the // worklist, as determined by the privacy pass - ast::item_static(..) | ast::item_ty(..) | + ast::item_ty(..) | ast::item_mod(..) | ast::item_foreign_mod(..) | ast::item_impl(..) | ast::item_trait(..) | ast::item_struct(..) | ast::item_enum(..) => {} diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f992411a548..d4586fc5990 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2521,9 +2521,12 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef { // requested if attr::contains_name(i.attrs, "address_insignificant"){ + if ccx.reachable.contains(&id) { + ccx.sess.span_bug(i.span, + "insignificant static is \ + reachable"); + } lib::llvm::SetUnnamedAddr(g, true); - lib::llvm::SetLinkage(g, - lib::llvm::InternalLinkage); // This is a curious case where we must make // all of these statics inlineable. If a