Skip to content

Couple of codegen_fn_attrs improvements #145429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(autodiff)]
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-module", module));

let name =
codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
codegen_fn_attrs.symbol_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id()));
let name = name.as_str();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name));
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
instance: Instance<'tcx>,
) -> bool {
fn is_llvm_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
if let Some(name) = tcx.codegen_fn_attrs(def_id).link_name {
if let Some(name) = tcx.codegen_fn_attrs(def_id).symbol_name {
name.as_str().starts_with("llvm.")
} else {
false
Expand Down
28 changes: 15 additions & 13 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, UsedBy};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
use rustc_middle::middle::codegen_fn_attrs::{
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
Expand Down Expand Up @@ -190,15 +189,21 @@ fn process_builtin_attrs(
match p {
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
AttributeKind::ExportName { name, .. } => {
codegen_fn_attrs.export_name = Some(*name)
codegen_fn_attrs.symbol_name = Some(*name)
}
AttributeKind::Inline(inline, span) => {
codegen_fn_attrs.inline = *inline;
interesting_spans.inline = Some(*span);
}
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
AttributeKind::LinkName { name, .. } => {
// FIXME Remove check for foreign functions once #[link_name] on non-foreign
// functions is a hard error
if tcx.is_foreign_item(did) {
codegen_fn_attrs.symbol_name = Some(*name);
}
}
AttributeKind::LinkOrdinal { ordinal, span } => {
codegen_fn_attrs.link_ordinal = Some(*ordinal);
interesting_spans.link_ordinal = Some(*span);
Expand Down Expand Up @@ -418,7 +423,7 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
// * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
// both for exports and imports through foreign items. This is handled further,
// during symbol mangling logic.
} else if codegen_fn_attrs.link_name.is_some() {
} else if codegen_fn_attrs.symbol_name.is_some() {
// * This can be overridden with the `#[link_name]` attribute
} else {
// NOTE: there's one more exception that we cannot apply here. On wasm,
Expand Down Expand Up @@ -473,7 +478,7 @@ fn check_result(
}

// error when specifying link_name together with link_ordinal
if let Some(_) = codegen_fn_attrs.link_name
if let Some(_) = codegen_fn_attrs.symbol_name
&& let Some(_) = codegen_fn_attrs.link_ordinal
{
let msg = "cannot use `#[link_name]` with `#[link_ordinal]`";
Expand Down Expand Up @@ -520,14 +525,11 @@ fn handle_lang_items(
// strippable by the linker.
//
// Additionally weak lang items have predetermined symbol names.
if let Some(lang_item) = lang_item {
if WEAK_LANG_ITEMS.contains(&lang_item) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
}
if let Some(link_name) = lang_item.link_name() {
codegen_fn_attrs.export_name = Some(link_name);
codegen_fn_attrs.link_name = Some(link_name);
}
if let Some(lang_item) = lang_item
&& let Some(link_name) = lang_item.link_name()
{
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
codegen_fn_attrs.symbol_name = Some(link_name);
}

// error when using no_mangle on a lang item item
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/foreign_modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl ClashingExternDeclarations {
/// symbol's name.
fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> SymbolName {
if let Some((overridden_link_name, overridden_link_name_span)) =
tcx.codegen_fn_attrs(fi).link_name.map(|overridden_link_name| {
tcx.codegen_fn_attrs(fi).symbol_name.map(|overridden_link_name| {
// FIXME: Instead of searching through the attributes again to get span
// information, we could have codegen_fn_attrs also give span information back for
// where the attribute was defined. However, until this is found to be a
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ impl<'tcx> Collector<'tcx> {
.link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));

let name = codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item));
let name = codegen_fn_attrs.symbol_name.unwrap_or_else(|| self.tcx.item_name(item));

if self.tcx.sess.target.binary_format == BinaryFormat::Elf {
let name = name.as_str();
Expand Down
17 changes: 6 additions & 11 deletions compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,10 @@ pub struct CodegenFnAttrs {
pub inline: InlineAttr,
/// Parsed representation of the `#[optimize]` attribute
pub optimize: OptimizeAttr,
/// The `#[export_name = "..."]` attribute, indicating a custom symbol a
/// function should be exported under
pub export_name: Option<Symbol>,
/// The `#[link_name = "..."]` attribute, indicating a custom symbol an
/// imported function should be imported as. Note that `export_name`
/// probably isn't set when this is set, this is for foreign items while
/// `#[export_name]` is for Rust-defined functions.
pub link_name: Option<Symbol>,
/// The name this function will be imported/exported under. This can be set
/// using the `#[export_name = "..."]` or `#[link_name = "..."]` attribute
/// depending on if this is a function definition or foreign function.
pub symbol_name: Option<Symbol>,
/// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
/// imported function has in the dynamic library. Note that this must not
/// be set when `link_name` is set. This is for foreign items with the
Expand Down Expand Up @@ -170,8 +166,7 @@ impl CodegenFnAttrs {
flags: CodegenFnAttrFlags::empty(),
inline: InlineAttr::None,
optimize: OptimizeAttr::Default,
export_name: None,
link_name: None,
symbol_name: None,
link_ordinal: None,
target_features: vec![],
safe_target_features: false,
Expand Down Expand Up @@ -200,7 +195,7 @@ impl CodegenFnAttrs {

self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|| self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|| self.export_name.is_some()
|| self.symbol_name.is_some()
|| match self.linkage {
// These are private, so make sure we don't try to consider
// them external.
Expand Down
50 changes: 17 additions & 33 deletions compiler/rustc_symbol_mangling/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,29 +193,20 @@ fn compute_symbol_name<'tcx>(
// defining crate.
// Weak lang items automatically get #[rustc_std_internal_symbol]
// applied by the code computing the CodegenFnAttrs.
// We are mangling all #[rustc_std_internal_symbol] items that don't
// also have #[no_mangle] as a combination of the rustc version and the
// unmangled linkage name. This is to ensure that if we link against a
// staticlib compiled by a different rustc version, we don't get symbol
// conflicts or even UB due to a different implementation/ABI. Rust
// staticlibs currently export all symbols, including those that are
// hidden in cdylibs.
// We are mangling all #[rustc_std_internal_symbol] items as a
// combination of the rustc version and the unmangled linkage name.
// This is to ensure that if we link against a staticlib compiled by a
// different rustc version, we don't get symbol conflicts or even UB
// due to a different implementation/ABI. Rust staticlibs currently
// export all symbols, including those that are hidden in cdylibs.
// We are using the v0 symbol mangling scheme here as we need to be
// consistent across all crates and in some contexts the legacy symbol
// mangling scheme can't be used. For example both the GCC backend and
// Rust-for-Linux don't support some of the characters used by the
// legacy symbol mangling scheme.
let name = if tcx.is_foreign_item(def_id) {
if let Some(name) = attrs.link_name { name } else { tcx.item_name(def_id) }
} else {
if let Some(name) = attrs.export_name { name } else { tcx.item_name(def_id) }
};
let name = if let Some(name) = attrs.symbol_name { name } else { tcx.item_name(def_id) };

if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
return name.to_string();
} else {
return v0::mangle_internal_symbol(tcx, name.as_str());
}
return v0::mangle_internal_symbol(tcx, name.as_str());
}

let wasm_import_module_exception_force_mangling = {
Expand All @@ -240,23 +231,16 @@ fn compute_symbol_name<'tcx>(
&& tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&def_id.into())
};

if let Some(name) = attrs.link_name
&& !wasm_import_module_exception_force_mangling
{
// Use provided name
return name.to_string();
}

if let Some(name) = attrs.export_name {
// Use provided name
return name.to_string();
}
if !wasm_import_module_exception_force_mangling {
if let Some(name) = attrs.symbol_name {
// Use provided name
return name.to_string();
}

if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
&& !wasm_import_module_exception_force_mangling
{
// Don't mangle
return tcx.item_name(def_id).to_string();
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
// Don't mangle
return tcx.item_name(def_id).to_string();
}
}

// If we're dealing with an instance of a function that's inlined from
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
return interp_ok(());
}
// Skip over items without an explicitly defined symbol name.
if !(attrs.export_name.is_some()
if !(attrs.symbol_name.is_some()
|| attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|| attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL))
{
Expand Down
Loading