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:
parent
18084be316
commit
2bd80758a2
2 changed files with 45 additions and 14 deletions
|
@ -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(..) => {}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue