[cfe-dev] Mangling & linkage of unnamed but instantiated nested classes

Richard Smith richard at metafoo.co.uk
Wed Oct 31 14:22:38 PDT 2012


On Wed, Oct 31, 2012 at 1:53 PM, John McCall <rjmccall at apple.com> wrote:
> On Oct 31, 2012, at 12:37 PM, David Blaikie wrote:
>> GCC 4.7 mangles them as:
>>
>> _Z1fIN1SUt_EEiT_
>> _Z1fIN1SUt0_EEiT_
>> _Z1fIN1TUt_EEiT_
>> _Z1fIN1TUt0_EEiT_
>>
>> I don't think we have any class-specific unnamed nested type counter
>> that would implement that Ut_, Ut0_, ... mangling scheme, though I can
>> imagine where one might be added (I'm not very familiar with IRGen
>> though, so I'll certainly be happy to have any pointers about how that
>> could/should be implemented).
>
> Probably we would want to record and remember this in the AST.
>
> This schema is indeed the one blessed by the ABI.
>    <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
> But as the ABI also notes:
>   The mangling of such unnamed types defined in namespace scope is generally unspecified because they do not have to match across translation units. An implementation must only ensure that naming collisions are avoided.
>
> The interesting question is what linkage GCC actually gives these symbols.

For the following:

struct S {
  struct {
    int f() {}
    struct {} n;
  } s;
};
int k1 = S().s.f();
decltype(S().s.n) n1;

struct {
  int g() {}
  struct {} n;
} s;
int k2 = s.g();
decltype(s.n) n2;

Run through g++-4.7 -S and nm, we get:

0000000000000000 t _ZN1SUt_1fEv
000000000000000a t _ZN3._21gEv
0000000000000004 B n1
000000000000000d b n2

So... it looks like g++ believes that S::<anon>::n's type has external
linkage (because n1 has external linkage), and s.n's type has internal
linkage (because n2 has internal linkage). It also looks like g++
believes both S::<anon>::f and <anon>::g don't need to be linked
across TUs, in violation of [basic.def.odr]p6's requirement that "the
program shall behave as if there were a single definition of
[S::<anon>]".



More information about the cfe-dev mailing list