On 9/27/26 1:12 PM, Iain Sandoe wrote:
Hi Jason,
On 27 Sep 2026, at 17:59, Jason Merrill <[email protected]> wrote:
On 9/27/26 11:01 AM, Iain Sandoe wrote:
While chasing two testsuite fails for -Os this wrong-code bug surfaced.
Fix tested on x86_64-linux/darwin. OK for trunk / backports?
thanks
Iain
--- 8< ---
For Darwin, at least, when -Os is selected we attempt to declone cdtors
since the platform does not support strong symbol aliases the clones
are emitted verbatim, leading to larger binaries.
The unified cdtor is a private implementational detail local to a TU
and so we should not emit a thunk if that will not be emitted.
Hmm, isn't the unified ctor linkonce when the separate ctors are?
The bug I was seeing was that the thunk got inlined leaving a reference to
a C4 that was not emitted; It is quite hard to reproduce since it requires the
right combination of sizes - but the libstdc++ testsuite triggers it reliably
(was
just not able to simplify that). Maybe your comment means that there’s
another issue (although the prohibition of the vague-linkage solves it, perhaps
that’s a side-effect).
Likewise, a thunk and the unified body must be selected together at
link time; for a vague-linkage cdtor COMDAT groups support this but,
without COMDAT, there is no guarantee and so we have to decline the
declone and emit ordinary clones instead.
It's desirable that they are selected together, but is it really necessary? As
long as one is selected, I'd think they should work interchangeably.
In principle, I suppose so - they are all supposed to be token-identical (let’s
not get into the ‘different TUs with different opts’).
So long as the call to the thunkee is properly indirected (either through the
GOT [64b] or a machopic indirect symbol [32b]), the static linker should be ok.
If the call goes directly we would get a warning.
Not sure exactly what avenue to explore on this - it’s a real end-user issue
since -Os is a “recommended setting” on the platform.
This sounds like a duplicate of 125359. As I wrote in response to a
patch a few months ago which would have similarly disabled
-fdeclone-ctor-dtor:
--
I can see the same failure on x86_64-pc-linux-gnu if I change
can_alias_cdtor to always return false.
I suspect the problem is that we instantiate the constructor for
inlining, and we inline the C1 thunk, but then decide not to inline the
C4 constructor, and don't realize that this means we can't inline C1
either.
--
I imagine this breaks with libstdc++ specifically because the extern
template causes us to avoid emitting an out-of-line copy of the C4, and
instead referring to the one in the library...but there isn't one,
because the library wasn't built with -fdeclone-ctor-dtor. Or, on a
platform with COMDAT groups, because it's an internal symbol anyway.
Jason