From 206b951803a5976cdb3f5fe6edb9deba65482900 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 19 Jun 2023 13:39:17 +0000 Subject: [PATCH] Fix linker failures when #[global_allocator] is used in a dependency --- compiler/rustc_codegen_ssa/src/base.rs | 18 ++++++++++++++++-- .../allocator-shim-circular-deps/Makefile | 7 +++++++ .../allocator-shim-circular-deps/main.rs | 5 +++++ .../allocator-shim-circular-deps/my_lib.rs | 10 ++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/run-make/allocator-shim-circular-deps/Makefile create mode 100644 tests/run-make/allocator-shim-circular-deps/main.rs create mode 100644 tests/run-make/allocator-shim-circular-deps/my_lib.rs diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index dc4a28c866ff3..6abc56d597562 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -13,7 +13,7 @@ use crate::mir::place::PlaceRef; use crate::traits::*; use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind}; -use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::allocator::{global_fn_name, AllocatorKind, ALLOCATOR_METHODS}; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; @@ -921,7 +921,21 @@ impl CrateInfo { missing_weak_lang_items .iter() .map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)), - ) + ); + if tcx.allocator_kind(()).is_some() { + // At least one crate needs a global allocator. This crate may be placed + // after the crate that defines it in the linker order, in which case some + // linkers return an error. By adding the global allocator shim methods to + // the linked_symbols list, linking the generated symbols.o will ensure that + // circular dependencies involving the global allocator don't lead to linker + // errors. + linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| { + ( + format!("{prefix}{}", global_fn_name(method.name).as_str()), + SymbolExportKind::Text, + ) + })); + } }); } diff --git a/tests/run-make/allocator-shim-circular-deps/Makefile b/tests/run-make/allocator-shim-circular-deps/Makefile new file mode 100644 index 0000000000000..4624b84680369 --- /dev/null +++ b/tests/run-make/allocator-shim-circular-deps/Makefile @@ -0,0 +1,7 @@ +# ignore-cross-compile +include ../tools.mk + +all: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) my_lib.rs + $(RUSTC) main.rs --test --extern my_lib=$(TMPDIR)/libmy_lib.rlib diff --git a/tests/run-make/allocator-shim-circular-deps/main.rs b/tests/run-make/allocator-shim-circular-deps/main.rs new file mode 100644 index 0000000000000..e317c657150a8 --- /dev/null +++ b/tests/run-make/allocator-shim-circular-deps/main.rs @@ -0,0 +1,5 @@ +#![crate_type = "bin"] + +fn main() { + my_lib::do_something(); +} diff --git a/tests/run-make/allocator-shim-circular-deps/my_lib.rs b/tests/run-make/allocator-shim-circular-deps/my_lib.rs new file mode 100644 index 0000000000000..095b103611697 --- /dev/null +++ b/tests/run-make/allocator-shim-circular-deps/my_lib.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +use std::alloc::System; + +#[global_allocator] +static ALLOCATOR: System = System; + +pub fn do_something() { + format!("allocating a string!"); +}