1
Fork 0

Continue tightening holes in reachability

* Don't flag any address_insignificant statics as reachable because the whole
  point of the address_insignificant optimization is that the static is not
  reachable. Additionally, there's no need for it to be reachable because LLVM
  optimizes it away.

* Be sure to not leak external node ids into our reachable set, this can
  spuriously cause local items to be considered reachable if the node ids just
  happen to line up
This commit is contained in:
Alex Crichton 2013-12-01 17:56:55 -08:00
parent 18084be316
commit 2bd80758a2
2 changed files with 45 additions and 14 deletions

View file

@ -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(..) => {}

View file

@ -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