Skip to content
Merged
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_attr_ir/src/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ impl<ScopeId> StrippedCfgItem<ScopeId> {
#[derive(StableHash, PrintAttribute)]
pub enum Linkage {
AvailableExternally,
Common,
ExternalWeak,
External,
Internal,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_attr_ir/src/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ impl AttributeKind {
Linkage(linkage, _) => match *linkage {
crate::Linkage::Internal => false,
crate::Linkage::AvailableExternally
| crate::Linkage::Common
| crate::Linkage::External
| crate::Linkage::ExternalWeak
| crate::Linkage::LinkOnceAny
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,10 +685,7 @@ impl SingleAttributeParser for LinkageParser {
]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: [
"available_externally",
"common",
"extern_weak",
"external",
"internal",
"linkonce",
"linkonce_odr",
"weak",
Expand All @@ -711,10 +708,7 @@ impl SingleAttributeParser for LinkageParser {
// and don't have to be, LLVM treats them as no-ops.
let linkage = match value {
sym::available_externally => Linkage::AvailableExternally,
sym::common => Linkage::Common,
sym::extern_weak => Linkage::ExternalWeak,
sym::external => Linkage::External,
sym::internal => Linkage::Internal,
sym::linkonce => Linkage::LinkOnceAny,
sym::linkonce_odr => Linkage::LinkOnceODR,
sym::weak => Linkage::WeakAny,
Expand All @@ -725,10 +719,7 @@ impl SingleAttributeParser for LinkageParser {
name_value.value_span,
&[
sym::available_externally,
sym::common,
sym::extern_weak,
sym::external,
sym::internal,
sym::linkonce,
sym::linkonce_odr,
sym::weak,
Expand Down
19 changes: 4 additions & 15 deletions compiler/rustc_codegen_gcc/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,14 @@ pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
| Linkage::LinkOnceODR
| Linkage::WeakAny
| Linkage::WeakODR
| Linkage::ExternalWeak
| Linkage::Common => GlobalKind::Exported,
| Linkage::ExternalWeak => GlobalKind::Exported,
}
}

/// The attribute a global *definition* needs on top of its [`GlobalKind`] to get this linkage.
#[cfg(feature = "master")]
pub fn global_linkage_attribute<'gcc>(linkage: Linkage) -> Option<VarAttribute<'gcc>> {
match linkage {
Linkage::Common => Some(VarAttribute::Common),
_ if linkage_needs_weak_attribute(linkage) => Some(VarAttribute::Weak),
_ => None,
}
if linkage_needs_weak_attribute(linkage) { Some(VarAttribute::Weak) } else { None }
}

/// The type of a function *definition* with an explicit `#[linkage]`.
Expand All @@ -85,26 +80,20 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType {
| Linkage::LinkOnceODR
| Linkage::WeakAny
| Linkage::WeakODR
| Linkage::ExternalWeak
| Linkage::Common => FunctionType::Exported,
| Linkage::ExternalWeak => FunctionType::Exported,
}
}

/// Whether a definition with this linkage must carry the `weak` attribute, so that a strong
/// definition in another object file wins over it instead of clashing with it.
///
/// `common` is in here for functions only: GCC honours that attribute on a variable, but drops it
/// on a function, so a common function falls back to weak. Globals go through
/// `global_linkage_attribute` instead.
#[cfg(feature = "master")]
pub fn linkage_needs_weak_attribute(linkage: Linkage) -> bool {
match linkage {
Linkage::LinkOnceAny
| Linkage::LinkOnceODR
| Linkage::WeakAny
| Linkage::WeakODR
| Linkage::ExternalWeak
| Linkage::Common => true,
| Linkage::ExternalWeak => true,
Linkage::External | Linkage::AvailableExternally | Linkage::Internal => false,
}
}
Expand Down
21 changes: 2 additions & 19 deletions compiler/rustc_codegen_gcc/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ use rustc_hir::def_id::LOCAL_CRATE;
use rustc_log::tracing::trace;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{
self, Allocation, ConstAllocation, CtfeProvenance, ErrorHandled, Scalar as InterpScalar,
read_target_uint,
self, ConstAllocation, CtfeProvenance, ErrorHandled, Scalar as InterpScalar, read_target_uint,
};
use rustc_middle::mono::MonoItem;
use rustc_middle::ty::layout::LayoutOf;
Expand Down Expand Up @@ -113,12 +112,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
// NOTE: Alignment from attributes has already been applied to the allocation.
set_global_alignment(self, global, alloc.align);

// A common symbol is storage the linker allocates and zero-fills, so giving the definition
// an initializer — even an all-zero one — takes it back out of `.comm`. A non-zero one is
// kept: the symbol is then an ordinary definition, which is what GCC does with it too.
if attrs.linkage != Some(Linkage::Common) || !is_zero_initializer(alloc) {
global.global_set_initializer_rvalue(value);
}
global.global_set_initializer_rvalue(value);

// As an optimization, all shared statics which do not have interior
// mutability are placed into read-only memory.
Expand Down Expand Up @@ -458,17 +452,6 @@ pub(crate) fn const_alloc_to_gcc_uncached<'gcc>(
cx.const_struct(&llvals, true)
}

/// Whether this allocation is all zeroes, and so needs no initializer to be spelled out.
fn is_zero_initializer(alloc: &Allocation) -> bool {
alloc.provenance().ptrs().is_empty()
// This `inspect` is okay: it is within the bounds of the allocation, there is no provenance
// to misread, and it does not affect interpreter execution.
&& alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.size().bytes_usize())
.iter()
.all(|&byte| byte == 0)
}

fn codegen_static_initializer<'gcc, 'tcx>(
cx: &CodegenCx<'gcc, 'tcx>,
def_id: DefId,
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_codegen_gcc/tests/c/import_linkage.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@

#include <stdint.h>

int32_t external_value = 1;
int32_t available_externally_value = 2;
int32_t linkonce_value = 3;
int32_t linkonce_odr_value = 4;
int32_t weak_value = 5;
int32_t weak_odr_value = 6;
int32_t common_value = 7;
int32_t extern_weak_value = 8;
int32_t internal_value = 9;
11 changes: 1 addition & 10 deletions compiler/rustc_codegen_gcc/tests/c/static_linkage.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
/* Strong definitions of the statics that `tests/run/static_linkage.rs` also defines, but weakly.
* The linker has to keep these and drop the Rust ones; a backend that emits the Rust definitions
* as ordinary global symbols fails the link with a duplicate definition instead.
*
* `internal_static` is the opposite case: the Rust side keeps its own, and the two definitions
* coexist because the Rust one is local. */
* as ordinary global symbols fails the link with a duplicate definition instead. */

#include <stdint.h>

int32_t weak_static = 1;
int32_t weak_odr_static = 2;
int32_t linkonce_static = 3;
int32_t linkonce_odr_static = 4;
int32_t common_static = 5;
int32_t internal_static = 200;

/* `available_externally` promises the real definition lives elsewhere: a backend may read this one
* or emit an equivalent copy of the Rust initializer, so the two have to hold the same value. */
Expand All @@ -29,9 +24,5 @@ int32_t c_read_all(void)
return 13;
if (linkonce_odr_static != 4)
return 14;
if (common_static != 5)
return 15;
if (internal_static != 200)
return 16;
return 0;
}
18 changes: 0 additions & 18 deletions compiler/rustc_codegen_gcc/tests/run/import_linkage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ extern crate mini_core;
use mini_core::*;

extern "C" {
#[linkage = "external"]
static external_value: *const i32;
#[linkage = "available_externally"]
static available_externally_value: *const i32;
#[linkage = "linkonce"]
Expand All @@ -31,15 +29,8 @@ extern "C" {
static weak_value: *const i32;
#[linkage = "weak_odr"]
static weak_odr_value: *const i32;
#[linkage = "common"]
static common_value: *const i32;
#[linkage = "extern_weak"]
static extern_weak_value: *const i32;
// An import is an undefined reference whatever the flavour says. Upstream bug: rustc lowers
// this one to an internal declaration, which LLVM's verifier rejects ("Global is external, but
// doesn't have external or weak linkage!") and which crashes cg_llvm at -O3.
#[linkage = "internal"]
static internal_value: *const i32;

// Nothing defines this one, so it stays null instead of breaking the link.
#[linkage = "extern_weak"]
Expand All @@ -49,9 +40,6 @@ extern "C" {
#[no_mangle]
extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
unsafe {
if *external_value != 1 {
return 1;
}
if *available_externally_value != 2 {
return 2;
}
Expand All @@ -67,15 +55,9 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
if *weak_odr_value != 6 {
return 6;
}
if *common_value != 7 {
return 7;
}
if *extern_weak_value != 8 {
return 8;
}
if *internal_value != 9 {
return 9;
}
if undefined_value as usize != 0 {
return 10;
}
Expand Down
16 changes: 1 addition & 15 deletions compiler/rustc_codegen_gcc/tests/run/static_linkage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
// `tests/c/static_linkage.c`, which defines the overridable ones strongly.
//
// If `predefine_static` were to ignore its `linkage` argument outright, every static would come out as
// an ordinary global symbol: the overridable ones would clash with the C definitions at link time, and
// `internal` would export a symbol it should have kept private.
// an ordinary global symbol: the overridable ones would clash with the C definitions at link time.

#![feature(linkage, no_core)]
#![no_std]
Expand All @@ -34,16 +33,6 @@ pub static linkonce_static: i32 = 0;
#[no_mangle]
pub static linkonce_odr_static: i32 = 0;

// `common` is only valid on a mutable global: LLVM rejects a constant one.
#[linkage = "common"]
#[no_mangle]
pub static mut common_static: i32 = 0;

// Private to this crate, so the C definition of the same name is a different object.
#[linkage = "internal"]
#[no_mangle]
pub static internal_static: i32 = 100;

// Not overridden by the C side: the definition here is the one that survives.
#[linkage = "weak"]
#[no_mangle]
Expand All @@ -66,9 +55,6 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
return result;
}

if internal_static != 100 {
return 1;
}
if only_weak_static != 6 {
return 2;
}
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_codegen_gcc/tests/run/weak_function_linkage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ extern "C" fn linkonce_odr_function() -> i32 {
4
}

// `#[linkage = "common"]` is absent on purpose: a common symbol is `SHN_COMMON`, which the object
// format only allows for objects, so no backend can give a function that linkage.

// Not overridden by the C side: the definition here is the one that runs.
#[linkage = "weak"]
#[no_mangle]
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
Linkage::WeakODR => llvm::Linkage::WeakODRLinkage,
Linkage::Internal => llvm::Linkage::InternalLinkage,
Linkage::ExternalWeak => llvm::Linkage::ExternalWeakLinkage,
Linkage::Common => llvm::Linkage::CommonLinkage,
}
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ fn prefix_and_suffix<'tcx>(
// LTO can fail when internal linkage is used.
emit_fatal("naked functions may not have internal linkage")
}
Linkage::Common => emit_fatal("Functions may not have common linkage"),
Linkage::AvailableExternally => {
// this would make the function equal an extern definition
emit_fatal("Functions may not have available_externally linkage")
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_monomorphize/src/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,6 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
Linkage::WeakODR => "WeakODR",
Linkage::Internal => "Internal",
Linkage::ExternalWeak => "ExternalWeak",
Linkage::Common => "Common",
};

output.push('[');
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,6 @@ symbols! {
cold_path,
collapse_debuginfo,
column,
common,
compare_bytes,
compare_exchange,
compare_exchange_weak,
Expand Down Expand Up @@ -1176,7 +1175,6 @@ symbols! {
integer_max,
integer_min,
integral,
internal,
internal_eq_trait_method_impls,
internal_features,
interrupt,
Expand Down
10 changes: 0 additions & 10 deletions tests/codegen-llvm/direct-access-external-data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ unsafe extern "C" {

// When "linkage" is used, we generate an indirection global.
// Check dso_local is still applied to the actual global.
// CHECK: @EXTERNAL = external
// DEFAULT-SAME: dso_local
// PIE-NOT: dso_local
// DIRECT-SAME: dso_local
// INDIRECT-NOT: dso_local
// CHECK-SAME: global i8
#[linkage = "external"]
safe static EXTERNAL: *const u32;

// CHECK: @WEAK = extern_weak
// DEFAULT-SAME: dso_local
// PIE-NOT: dso_local
Expand All @@ -44,6 +35,5 @@ unsafe extern "C" {
#[no_mangle]
pub fn refer() {
core::hint::black_box(VAR);
core::hint::black_box(EXTERNAL);
core::hint::black_box(WEAK);
}
10 changes: 0 additions & 10 deletions tests/codegen-llvm/loongarch/direct-access-external-data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ unsafe extern "C" {

// When "linkage" is used, we generate an indirection global.
// Check dso_local is still applied to the actual global.
// CHECK: @EXTERNAL = external
// DEFAULT-NOT: dso_local
// PIE-NOT: dso_local
// DIRECT-SAME: dso_local
// INDIRECT-NOT: dso_local
// CHECK-SAME: global i8
#[linkage = "external"]
safe static EXTERNAL: *const u32;

// CHECK: @WEAK = extern_weak
// DEFAULT-NOT: dso_local
// PIE-NOT: dso_local
Expand All @@ -42,6 +33,5 @@ unsafe extern "C" {
#[no_mangle]
pub fn refer() {
core::hint::black_box(VAR);
core::hint::black_box(EXTERNAL);
core::hint::black_box(WEAK);
}
2 changes: 1 addition & 1 deletion tests/run-make/linkage-attr-on-static/bar.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(linkage)]

#[no_mangle]
#[linkage = "external"]
#[linkage = "weak"]
static BAZ: i32 = 21;

#[link(name = "foo", kind = "static")]
Expand Down
2 changes: 2 additions & 0 deletions tests/run-make/linkage-attr-on-static/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

//@ ignore-cross-compile
// Reason: the compiled binary is executed
//@ ignore-i686-pc-windows-gnu weak symbols broken with MinGW linker
//@ ignore-x86_64-pc-windows-gnu weak symbols broken with MinGW linker

use run_make_support::{build_native_static_lib, run, rustc};

Expand Down
Loading
Loading