Skip to content

Commit a64b2a9

Browse files
committed
Move #[used] check for Mach-O to rustc_typeck from rustc_codegen_llvm
1 parent da72295 commit a64b2a9

File tree

2 files changed

+38
-28
lines changed

2 files changed

+38
-28
lines changed

compiler/rustc_codegen_llvm/src/consts.rs

+7-27
Original file line numberDiff line numberDiff line change
@@ -543,33 +543,13 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
543543
// in the handling of `.init_array` (the static constructor list) in versions of
544544
// the gold linker (prior to the one released with binutils 2.36).
545545
//
546-
// However, unconditional use of `llvm.compiler.used` caused a nontrivial amount of
547-
// ecosystem breakage, especially on Mach-O targets. To resolve this, we compile it
548-
// as llvm.compiler.used on ELF targets and llvm.used elsewhere, which should be
549-
// equivalent to how we compiled `#[used]` before LLVM 13, as `llvm.used` and
550-
// `llvm.compiler.used` were treated the same on ELF targets prior in earlier LLVM
551-
// versions (additionally, it seems to be how Clang handles `__attribute__((used))`,
552-
// perhaps for similar compatibility-motivated reasons).
553-
//
554-
// See https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146 and
555-
// following comments for some discussion of this.
556-
//
557-
// The final wrinkle is it's not really clear how to tell if we're going to output
558-
// ELF, so it's been approximated as "not like wasm, osx, or windows", which is
559-
// not exactly correct, but is pretty close and hopefully handles all the platforms
560-
// platforms where old versions of `ld.gold` are likely to show up.
561-
//
562-
// All this is subject to change in the future. Which is a good thing, because this
563-
// probably should be firmed up somehow!
564-
let seems_like_elf = !(self.tcx.sess.target.is_like_osx
565-
|| self.tcx.sess.target.is_like_windows
566-
|| self.tcx.sess.target.is_like_wasm);
567-
568-
if seems_like_elf {
569-
self.add_compiler_used_global(g);
570-
} else {
571-
self.add_used_global(g);
572-
}
546+
// That said, we only ever emit these when compiling for ELF targets, unless
547+
// `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
548+
// on other targets, in particular MachO targets have *their* static constructor
549+
// lists broken if `llvm.compiler.used` is emitted rather than llvm.used. However,
550+
// that check happens when assigning the `CodegenFnAttrFlags` in `rustc_typeck`,
551+
// so we don't need to take care of it here.
552+
self.add_compiler_used_global(g);
573553
}
574554
if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {
575555
// `USED` and `USED_LINKER` can't be used together.

compiler/rustc_typeck/src/collect.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -2850,7 +2850,37 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
28502850
)
28512851
.emit();
28522852
}
2853-
None => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED,
2853+
None => {
2854+
// Unfortunately, unconditionally using `llvm.used` causes
2855+
// issues in handling `.init_array` with the gold linker,
2856+
// but using `llvm.compiler.used` caused a nontrival amount
2857+
// of unintentional ecosystem breakage -- particularly on
2858+
// Mach-O targets.
2859+
//
2860+
// As a result, we emit `llvm.compiler.used` only on ELF
2861+
// targets. This is somewhat ad-hoc, but actually follows
2862+
// our pre-LLVM 13 behavior (prior to the ecosystem
2863+
// breakage), and seems to match `clang`'s behavior as well
2864+
// (both before and after LLVM 13), possibly because they
2865+
// have similar compatibility concerns to us. See
2866+
// https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146
2867+
// and following comments for some discussion of this, as
2868+
// well as the comments in `rustc_codegen_llvm` where these
2869+
// flags are handled.
2870+
//
2871+
// Anyway, to be clear: this is still up in the air
2872+
// somewhat, and is subject to change in the future (which
2873+
// is a good thing, because this would ideally be a bit
2874+
// more firmed up).
2875+
let is_like_elf = !(tcx.sess.target.is_like_osx
2876+
|| tcx.sess.target.is_like_windows
2877+
|| tcx.sess.target.is_like_wasm);
2878+
codegen_fn_attrs.flags = if is_like_elf {
2879+
CodegenFnAttrFlags::USED
2880+
} else {
2881+
CodegenFnAttrFlags::USED_LINKER
2882+
};
2883+
}
28542884
}
28552885
} else if attr.has_name(sym::cmse_nonsecure_entry) {
28562886
if !matches!(tcx.fn_sig(did).abi(), abi::Abi::C { .. }) {

0 commit comments

Comments
 (0)