Rollup merge of #150494 - extern_linkage_dso_local, r=bjorn3

Fix dso_local for external statics with linkage

Tracking issue of the feature: rust-lang/rust#127488

DSO local attributes are not correctly applied to extern statics with `#[linkage = "foo"]` as we generate an internal global for such statics, and the we evaluate (and apply) DSO attributes on the internal one instead.

Fix this by applying DSO local attributes on the actually extern ones, too.
This commit is contained in:
Stuart Cook 2026-01-11 14:27:55 +11:00 committed by GitHub
commit 30585ebbd3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 10 deletions

View file

@ -187,6 +187,10 @@ fn check_and_apply_linkage<'ll, 'tcx>(
};
llvm::set_linkage(g1, base::linkage_to_llvm(linkage));
// Normally this is done in `get_static_inner`, but when as we generate an internal global,
// it will apply the dso_local to the internal global instead, so do it here, too.
cx.assume_dso_local(g1, true);
// Declare an internal global `extern_with_linkage_foo` which
// is initialized with the address of `foo`. If `foo` is
// discarded during linking (for example, if `foo` has weak

View file

@ -1,21 +1,48 @@
//@ only-loongarch64-unknown-linux-gnu
//@ ignore-powerpc64 (handles dso_local differently)
//@ ignore-apple (handles dso_local differently)
//@ revisions: DEFAULT DIRECT INDIRECT
//@ revisions: DEFAULT PIE DIRECT INDIRECT
//@ [DEFAULT] compile-flags: -C relocation-model=static
//@ [DIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=yes
//@ [PIE] compile-flags: -C relocation-model=pie
//@ [DIRECT] compile-flags: -C relocation-model=pie -Z direct-access-external-data=yes
//@ [INDIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=no
#![crate_type = "rlib"]
#![feature(linkage)]
// DEFAULT: @VAR = external {{.*}} global i32
// DIRECT: @VAR = external dso_local {{.*}} global i32
// INDIRECT: @VAR = external {{.*}} global i32
unsafe extern "C" {
// CHECK: @VAR = external
// DEFAULT-SAME: dso_local
// PIE-NOT: dso_local
// DIRECT-SAME: dso_local
// INDIRECT-NOT: dso_local
// CHECK-SAME: global i32
safe static VAR: i32;
extern "C" {
static VAR: i32;
// 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
// DIRECT-SAME: dso_local
// INDIRECT-NOT: dso_local
// CHECK-SAME: global i8
#[linkage = "extern_weak"]
safe static WEAK: *const u32;
}
#[no_mangle]
pub fn get() -> i32 {
unsafe { VAR }
pub fn refer() {
core::hint::black_box(VAR);
core::hint::black_box(EXTERNAL);
core::hint::black_box(WEAK);
}