Skip to content

Commit 46f6422

Browse files
committed
Make #[used(linker)] the default on ELF too
#[used] currently is an alias for #[used(linker)] on all platforms except ELF based ones where it is an alias for #[used(compiler)]. The latter has surprising behavior and the LLVM LangRef explicitly states that it "should only be used in rare circumstances, and should not be exposed to source languages." The reason #[used] still was an alias to #[used(compiler)] on ELF is because the gold linker has issues with it. Luckily gold has been deprecated with GCC 15 and seems to be unable to bootstrap rustc anyway. As such we shouldn't really care about supporting gold.
1 parent dcecb99 commit 46f6422

File tree

3 files changed

+15
-37
lines changed

3 files changed

+15
-37
lines changed

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -546,12 +546,12 @@ impl<'ll> CodegenCx<'ll, '_> {
546546
// in the handling of `.init_array` (the static constructor list) in versions of
547547
// the gold linker (prior to the one released with binutils 2.36).
548548
//
549-
// That said, we only ever emit these when compiling for ELF targets, unless
550-
// `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
551-
// on other targets, in particular MachO targets have *their* static constructor
552-
// lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
553-
// that check happens when assigning the `CodegenFnAttrFlags` in
554-
// `rustc_hir_analysis`, so we don't need to take care of it here.
549+
// That said, we only ever emit these when `#[used(compiler)]` is explicitly
550+
// requested. This is to avoid similar breakage on other targets, in particular
551+
// MachO targets have *their* static constructor lists broken if `llvm.compiler.used`
552+
// is emitted rather than `llvm.used`. However, that check happens when assigning
553+
// the `CodegenFnAttrFlags` in `rustc_hir_analysis`, so we don't need to take care
554+
// of it here.
555555
self.add_compiler_used_global(g);
556556
}
557557
if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,7 +1986,7 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor
19861986
/// This method creates a synthetic object file, which contains undefined references to all symbols
19871987
/// that are necessary for the linking. They are only present in symbol table but not actually
19881988
/// used in any sections, so the linker will therefore pick relevant rlibs for linking, but
1989-
/// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections.
1989+
/// unused `#[no_mangle]` or `#[used(compiler)]` can still be discard by GC sections.
19901990
///
19911991
/// There's a few internal crates in the standard library (aka libcore and
19921992
/// libstd) which actually have a circular dependence upon one another. This
@@ -2020,7 +2020,8 @@ fn add_linked_symbol_object(
20202020

20212021
if file.format() == object::BinaryFormat::MachO {
20222022
// Divide up the sections into sub-sections via symbols for dead code stripping.
2023-
// Without this flag, unused `#[no_mangle]` or `#[used]` cannot be discard on MachO targets.
2023+
// Without this flag, unused `#[no_mangle]` or `#[used(compiler)]` cannot be
2024+
// discard on MachO targets.
20242025
file.set_subsections_via_symbols();
20252026
}
20262027

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -195,35 +195,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
195195
tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() });
196196
}
197197
None => {
198-
// Unfortunately, unconditionally using `llvm.used` causes
199-
// issues in handling `.init_array` with the gold linker,
200-
// but using `llvm.compiler.used` caused a nontrivial amount
201-
// of unintentional ecosystem breakage -- particularly on
202-
// Mach-O targets.
203-
//
204-
// As a result, we emit `llvm.compiler.used` only on ELF
205-
// targets. This is somewhat ad-hoc, but actually follows
206-
// our pre-LLVM 13 behavior (prior to the ecosystem
207-
// breakage), and seems to match `clang`'s behavior as well
208-
// (both before and after LLVM 13), possibly because they
209-
// have similar compatibility concerns to us. See
210-
// https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146
211-
// and following comments for some discussion of this, as
212-
// well as the comments in `rustc_codegen_llvm` where these
213-
// flags are handled.
214-
//
215-
// Anyway, to be clear: this is still up in the air
216-
// somewhat, and is subject to change in the future (which
217-
// is a good thing, because this would ideally be a bit
218-
// more firmed up).
219-
let is_like_elf = !(tcx.sess.target.is_like_darwin
220-
|| tcx.sess.target.is_like_windows
221-
|| tcx.sess.target.is_like_wasm);
222-
codegen_fn_attrs.flags |= if is_like_elf {
223-
CodegenFnAttrFlags::USED
224-
} else {
225-
CodegenFnAttrFlags::USED_LINKER
226-
};
198+
// Unconditionally using `llvm.used` causes issues in handling
199+
// `.init_array` with the gold linker. Luckily gold has been
200+
// deprecated with GCC 15 and seems to be unable to bootstrap
201+
// rustc anyway. As such we don't really care about supporting
202+
// gold.
203+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER
227204
}
228205
}
229206
}

0 commit comments

Comments
 (0)