https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125418
--- Comment #18 from Matt Turner <mattst88 at gmail dot com> ---
(In reply to Alexander Monakov from comment #17)
> As H.J.Lu mentioned, the linker will not see the attribute and can upgrade
> initial-exec to local-exec anyway. I don't see the point of "honoring" the
> attribute in GCC without a clear rationale.
Fair enough. And ld does the upgrade in practice, not just in principle.
Compiled with -fPIC so the object really does contain GOTTPREL:
static __thread int xyzzy __attribute__ ((tls_model ("initial-exec")));
void set (int v) { xyzzy = v; }
int foo (void) { return xyzzy; }
the .o has two GOTTPREL relocs, and after linking -no-pie foo() is
ldah gp,2(t12)
lda gp,31296(gp)
rduniq
lda t0,16
addq v0,t0,v0
ldl v0,0(v0)
ret
with no TPREL dynamic relocs left. Same code whichever model GCC picks, so
there's nothing to appeal to. I think gcc.dg/tls/alpha-1.c should be fixed
rather than the compiler: it uses a variable defined in the same file, where
local-exec is a valid implementation, so making it extern keeps it testing the
IE sequence.
> I don't follow. GCC doesn't "drop" the attribute, it takes it and then
> upgrades the TLS model exactly because it is safe (the linker is allowed to
> do the same upgrade).
Agreed, "discarded" was the wrong word.
> Why? You already did it for the C front-end, and I think we came to an
> agreement that the problem is with 'pragma weak' processing
Right, I'll ping that one. One thing worth having for it: C++ has the same
problem, and it isn't source ordering.
extern __thread int foo __attribute__((visibility("hidden"), weak));
int *f (void) { return &foo; } -> gottprel
extern __thread int foo __attribute__((visibility("hidden")));
#pragma weak foo
int *f (void) { return &foo; } -> tprelhi
Putting the #pragma before the declaration gives tprelhi as well, so DECL_WEAK
just isn't set yet when the model is computed. cc1plus behaves the same, so the
pragma weak fix probably needs a C++ counterpart.