https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125418
--- Comment #16 from Matt Turner <mattst88 at gmail dot com> ---
The linker side is fixed and shipping: ffea43122dc5 ("alpha: Properly handle
local weak undefined symbols", PR ld/34165) is in binutils 2.47, and Gentoo
backports it onto 2.46.1. I verified it against binutils 2.46.1 with that
patch applied -- the four ld-alpha testcases added by the commit link
correctly, and the disassembly matches the expected output in
tlsbin-weak-undef1.d.
With the fixed linker in place, GCC still emits the wrong relocation, so I
don't think the linker fix resolves this PR. Three data points from current
trunk (17.0.0 20260811), cross to alpha-unknown-linux-gnu and native
x86_64-pc-linux-gnu:
1) GCC's own testsuite catches this. gcc.dg/tls/alpha-1.c is
static __thread int xyzzy __attribute__ ((tls_model ("initial-exec")));
int foo(void) { return xyzzy; }
/* { dg-final { scan-assembler "gottprel" } } */
/* { dg-final { scan-assembler-not "tprel(lo|hi|16)" } } */
and it fails on trunk, because GCC emits !tprelhi/!tprello. This is
dg-do compile, so no linker change can affect it. The test dates from the
original TLS support and exists specifically to check that an explicit
initial-exec is honored.
2) The attribute is discarded unconditionally, not only for hidden symbols.
For a locally defined variable, all four tls_model values collapse to
local-exec:
static __thread int x __attribute__((tls_model("global-dynamic")));
int foo(void) { return x; }
$ gcc -fno-pie -S
trunk: @tpoff (x86_64) !tprelhi (alpha)
GCC 15: @tlsgd (x86_64)
Same for local-dynamic and initial-exec. This particular case is harmless --
local-exec is a valid implementation for a variable defined in a non-PIC
executable -- but it shows the explicit attribute is being dropped outright
rather than an optimization being applied where it happens to be safe. That
seems worth separating from the question of whether the linker can cope with
the result.
3) The C++ front end has the same problem, so a fix should cover both.
cp/decl2.cc (a0344144dbc, "c++: Update TLS model after processing a TLS
variable") carries the same unguarded upgrade as c-decl.cc (8cad8f94b45).
The testcase from comment #0 compiled as C++ also gives
Varpool flags: tls-local-exec
The guard used by ipa-visibility applies equally to both:
&& !lookup_attribute ("tls_model", DECL_ATTRIBUTES (*node))
I'll post a patch covering both front ends to gcc-patches.