rust/compiler
bors ceeb5ade20 Auto merge of #93718 - thomcc:used-macho, r=pnkfelix
Only compile #[used] as llvm.compiler.used for ELF targets

This returns `#[used]` to how it worked prior to the LLVM 13 update. The intention is not that this is a stable promise.

I'll add tests later today. The tests will test things that we don't actually promise, though.

It's a deliberately small patch, mostly comments. And assuming it's reviewed and lands in time, IMO it should at least be considered for uplifting to beta (so that it can be in 1.59), as the change broke many crates in the ecosystem, even if they are relying on behavior that is not guaranteed.

# Background

LLVM has two ways of preventing removal of an unused variable: `llvm.compiler.used`, which must be present in object files, but allows the linker to remove the value, and `llvm.used` which is supposed to apply to the linker as well, if possible.

Prior to LLVM 13, `llvm.used` and `llvm.compiler.used` were the same on ELF targets, although they were different elsewhere. Prior to our update to LLVM 13, we compiled `#[used]` using `llvm.used` unconditionally, even though we only ever promised behavior like `llvm.compiler.used`.

In LLVM 13, ELF targets gained some support for preventing linker removal of `llvm.used` via the SHF_RETAIN section flag. This has some compatibility issues though: Concretely: some older versions `ld.gold` (specifically ones prior to v2.36, released in Jan 2021) had a bug where it would fail to place a `#[used] #[link_section = ".init_array"]` static in between `__init_array_start`/`__init_array_end`, leading to code that does this failing to run a static constructor. This is technically not a thing we guarantee will work, is a common use case, and is needed in `libstd` (for example, to get access to `std::env::args()` even if Rust does not control `main`, such as when in a `cdylib` crate).

As a result, when updating to LLVM 13, we unconditionally switched to using `llvm.compiler.used`, which mirror the guarantees we make for `#[used]` and doesn't require the latest ld.gold. Unfortunately, this happened to break quite a bit of things in the ecosystem, as non-ELF targets had come to rely on `#[used]` being slightly stronger. In particular, there are cases where it will even break static constructors on these targets[^initinit] (and in fact, breaks way more use cases, as Mach-O uses special sections as an interface to the OS/linker/loader in many places).

As a result, we only switch to `llvm.compiler.used` on ELF[^elfish] targets. The rationale here is:

1. It is (hopefully) identical to the semantics we used prior to the LLVM13 update as prior to that update we unconditionally used `llvm.used`, but on ELF `llvm.used` was the same as `llvm.compiler.used`.

2. It seems to be how Clang compiles this, and given that they have similar (but stronger) compatibility promises, that makes sense.

[^initinit]: For Mach-O targets: It is not always guaranteed that `__DATA,__mod_init_func` is a GC root if it does not have the `S_MOD_INIT_FUNC_POINTERS` flag which we cannot add. In most cases, when ld64 transformed this section into `__DATA_CONST,__mod_init_func` it gets applied, but it's not clear that that is intentional (let alone guaranteed), and the logic is complex enough that it probably happens sometimes, and people in the wild report it occurring.

[^elfish]: Actually, there's not a great way to tell if it's ELF, so I've approximated it.

This is pretty ad-hoc and hacky! We probably should have a firmer set of guarantees here, but this change should relax the pressure on coming up with that considerably, returning it to previous levels.

---

Unsure who should review so leaving it open, but for sure CC `@nikic`
2022-07-21 06:59:32 +00:00
..
rustc Don't rerun the build script for the compiler each time on linux 2022-07-10 23:57:25 -05:00
rustc_apfloat Update smallvec to 1.8.1. 2022-06-27 08:48:55 +10:00
rustc_arena Rollup merge of #97711 - Nilstrieb:rustc-arena-ub, r=wesleywiser 2022-07-07 18:06:49 +05:30
rustc_ast Stabilize let_chains 2022-07-16 20:17:58 -03:00
rustc_ast_lowering Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_ast_passes Auto merge of #98180 - notriddle:notriddle/rustdoc-fn, r=petrochenkov,GuillaumeGomez 2022-07-19 19:36:57 +00:00
rustc_ast_pretty Parse closure binders 2022-07-12 16:25:16 +04:00
rustc_attr middle: add implies_by to #[unstable] 2022-07-20 14:53:01 +01:00
rustc_borrowck Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_builtin_macros Rollup merge of #99508 - TaKO8Ki:avoid-symbol-to-string-conversion-in-BuiltinLintDiagnostics, r=compiler-errors 2022-07-20 18:58:20 +02:00
rustc_codegen_cranelift Revert "Rollup merge of #98582 - oli-obk:unconstrained_opaque_type, r=estebank" 2022-07-20 07:55:58 +00:00
rustc_codegen_gcc Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_codegen_llvm Auto merge of #93718 - thomcc:used-macho, r=pnkfelix 2022-07-21 06:59:32 +00:00
rustc_codegen_ssa Auto merge of #93718 - thomcc:used-macho, r=pnkfelix 2022-07-21 06:59:32 +00:00
rustc_const_eval Auto merge of #99472 - RalfJung:provenance, r=oli-obk 2022-07-20 16:56:31 +00:00
rustc_data_structures Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_driver Rename debugging_opts to unstable_opts 2022-07-13 17:47:06 -05:00
rustc_error_codes Auto merge of #98180 - notriddle:notriddle/rustdoc-fn, r=petrochenkov,GuillaumeGomez 2022-07-19 19:36:57 +00:00
rustc_error_messages Auto merge of #98180 - notriddle:notriddle/rustdoc-fn, r=petrochenkov,GuillaumeGomez 2022-07-19 19:36:57 +00:00
rustc_errors Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_expand better error for bad depth on macro metavar expr 2022-07-19 16:41:32 +00:00
rustc_feature Stabilize let_chains 2022-07-16 20:17:58 -03:00
rustc_fs_util
rustc_graphviz Fully stabilize NLL 2022-06-03 17:16:41 -04:00
rustc_hir Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_hir_pretty use rustc_hir_pretty::qpath_to_string to avoid span_to_snippet when rendering path 2022-07-17 04:58:38 +00:00
rustc_incremental Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_index Use a bitset instead of a hash map in HIR ID validator 2022-07-04 08:30:13 +02:00
rustc_infer Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_interface Add flag to configure noalias on Box<T> 2022-07-19 16:02:59 +02:00
rustc_lexer fix typo in comment 2022-06-28 19:59:09 +05:30
rustc_lint Rollup merge of #99433 - cjgillot:erase-foreign-sig, r=compiler-errors 2022-07-20 11:29:39 +05:30
rustc_lint_defs avoid a Symbol to String conversion 2022-07-20 18:19:25 +09:00
rustc_llvm Auto merge of #98843 - Urgau:check-cfg-stage0, r=Mark-Simulacrum 2022-07-20 04:23:09 +00:00
rustc_log clippy::complexity fixes 2022-05-26 13:14:24 +02:00
rustc_macros macros: support adding warnings to diags 2022-07-15 16:13:49 +01:00
rustc_metadata passes: improved partial stabilization diagnostic 2022-07-20 14:53:01 +01:00
rustc_middle Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_mir_build Revert "Rollup merge of #98582 - oli-obk:unconstrained_opaque_type, r=estebank" 2022-07-20 07:55:58 +00:00
rustc_mir_dataflow Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_mir_transform Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_monomorphize use par_for_each_in in par_body_owners and collect_crate_mono_items 2022-07-19 17:00:51 +08:00
rustc_parse Stabilize let_chains 2022-07-16 20:17:58 -03:00
rustc_parse_format Add diagnostic width span when '0$' is used as width. 2022-07-20 13:39:56 +01:00
rustc_passes Auto merge of #99058 - michaelwoerister:remove-stable-set-and-map, r=nagisa 2022-07-20 22:19:30 +00:00
rustc_plugin_impl remove currently unused deps 2022-06-13 22:20:51 +03:00
rustc_privacy errors: lint on LintDiagnosticBuilder::build 2022-07-15 16:13:47 +01:00
rustc_query_impl Use constant eval to do strict validity checks 2022-07-14 22:55:17 +01:00
rustc_query_system Rename debugging_opts to unstable_opts 2022-07-13 17:47:06 -05:00
rustc_resolve Rollup merge of #99508 - TaKO8Ki:avoid-symbol-to-string-conversion-in-BuiltinLintDiagnostics, r=compiler-errors 2022-07-20 18:58:20 +02:00
rustc_save_analysis Rollup merge of #98705 - WaffleLapkin:closure_binder, r=cjgillot 2022-07-14 14:14:21 +05:30
rustc_serialize use BufReader for counting zero bytes 2022-07-02 22:51:42 +09:00
rustc_session Add flag to configure noalias on Box<T> 2022-07-19 16:02:59 +02:00
rustc_smir Rustfmt 2022-06-02 10:29:00 +00:00
rustc_span span: add span_extend_to_line helper 2022-07-20 14:53:01 +01:00
rustc_symbol_mangling Allow to create definitions inside the query system. 2022-07-06 22:50:55 +02:00
rustc_target Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_trait_selection take opaq types 2022-07-20 12:43:10 +03:00
rustc_traits Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_ty_utils Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_type_ir Remove unused StableMap and StableSet types from rustc_data_structures 2022-07-20 13:11:39 +02:00
rustc_typeck Auto merge of #93718 - thomcc:used-macho, r=pnkfelix 2022-07-21 06:59:32 +00:00