Skip to content

Commit

Permalink
Auto merge of #52993 - alexcrichton:fix-some-vis, r=michaelwoerister
Browse files Browse the repository at this point in the history
rustc: Tweak visibility of some lang items

This commit tweaks the linker-level visibility of some lang items that rustc
uses and defines. Notably this means that `#[panic_implementation]` and
`#[alloc_error_handler]` functions are never marked as `internal`. It's up to
the linker to eliminate these, not rustc.

Additionally `#[global_allocator]` generated symbols are no longer forced to
`Default` visibility (fully exported), but rather they're relaxed to `Hidden`
visibility). This symbols are *not* needed across DLL boundaries, only as a
local implementation detail of the compiler-injected allocator symbols, so
`Hidden` should suffice.

Closes #51342
Closes #52795
  • Loading branch information
bors committed Aug 8, 2018
2 parents 3f4f18f + 7c58ab6 commit 26d7b64
Show file tree
Hide file tree
Showing 9 changed files with 345 additions and 152 deletions.
11 changes: 7 additions & 4 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// makes all other generics or inline functions that it references
// reachable as well.

use hir::CodegenFnAttrs;
use hir::{CodegenFnAttrs, CodegenFnAttrFlags};
use hir::map as hir_map;
use hir::def::Def;
use hir::def_id::{DefId, CrateNum};
Expand All @@ -28,7 +28,6 @@ use util::nodemap::{NodeSet, FxHashSet};

use rustc_target::spec::abi::Abi;
use syntax::ast;
use syntax::attr;
use hir;
use hir::def_id::LOCAL_CRATE;
use hir::intravisit::{Visitor, NestedVisitorMap};
Expand Down Expand Up @@ -359,8 +358,12 @@ struct CollectPrivateImplItemsVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
// Anything which has custom linkage gets thrown on the worklist no
// matter where it is in the crate.
if attr::contains_name(&item.attrs, "linkage") {
// matter where it is in the crate, along with "special std symbols"
// which are currently akin to allocator symbols.
let def_id = self.tcx.hir.local_def_id(item.id);
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
if codegen_attrs.linkage.is_some() ||
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
self.worklist.push(item.id);
}

Expand Down
7 changes: 1 addition & 6 deletions src/librustc_allocator/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_errors;
use syntax::{
ast::{
self, Arg, Attribute, Crate, Expr, FnHeader, Generics, Ident, Item, ItemKind,
LitKind, Mac, Mod, Mutability, StrStyle, Ty, TyKind, Unsafety, VisibilityKind,
Mac, Mod, Mutability, Ty, TyKind, Unsafety, VisibilityKind,
},
attr,
codemap::{
Expand Down Expand Up @@ -236,17 +236,12 @@ impl<'a> AllocFnFactory<'a> {
}

fn attrs(&self) -> Vec<Attribute> {
let key = Symbol::intern("linkage");
let value = LitKind::Str(Symbol::intern("external"), StrStyle::Cooked);
let linkage = self.cx.meta_name_value(self.span, key, value);

let no_mangle = Symbol::intern("no_mangle");
let no_mangle = self.cx.meta_word(self.span, no_mangle);

let special = Symbol::intern("rustc_std_internal_symbol");
let special = self.cx.meta_word(self.span, special);
vec![
self.cx.attribute(self.span, linkage),
self.cx.attribute(self.span, no_mangle),
self.cx.attribute(self.span, special),
]
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_codegen_llvm/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
if tcx.sess.target.target.options.default_hidden_visibility {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
if tcx.sess.target.target.options.requires_uwtable {
attributes::emit_uwtable(llfn, true);
}
if tcx.sess.target.target.options.requires_uwtable {
attributes::emit_uwtable(llfn, true);
}

let callee = CString::new(kind.fn_name(method.name)).unwrap();
let callee = llvm::LLVMRustGetOrInsertFunction(llmod,
callee.as_ptr(),
ty);
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);

let llbb = llvm::LLVMAppendBasicBlockInContext(llcx,
llfn,
Expand Down
24 changes: 22 additions & 2 deletions src/librustc_codegen_llvm/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,8 +809,28 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
rx,
codegen_units.len());

// Codegen an allocator shim, if any
let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() {
// Codegen an allocator shim, if necessary.
//
// If the crate doesn't have an `allocator_kind` set then there's definitely
// no shim to generate. Otherwise we also check our dependency graph for all
// our output crate types. If anything there looks like its a `Dynamic`
// linkage, then it's already got an allocator shim and we'll be using that
// one instead. If nothing exists then it's our job to generate the
// allocator!
let any_dynamic_crate = tcx.sess.dependency_formats.borrow()
.iter()
.any(|(_, list)| {
use rustc::middle::dependency_format::Linkage;
list.iter().any(|linkage| {
match linkage {
Linkage::Dynamic => true,
_ => false,
}
})
});
let allocator_module = if any_dynamic_crate {
None
} else if let Some(kind) = *tcx.sess.allocator_kind.get() {
unsafe {
let llmod_id = "allocator";
let modules = ModuleLlvm::new(tcx.sess, llmod_id);
Expand Down
Loading

0 comments on commit 26d7b64

Please sign in to comment.