[cxx-abi-dev] missing mangling for <template-param> <template-args> in <unresolved-name>

Richard Smith richardsmith at google.com
Wed Feb 18 23:54:03 UTC 2015


On 18 February 2015 at 15:35, John McCall <rjmccall at apple.com> wrote:

> On Feb 18, 2015, at 1:45 PM, Richard Smith <richardsmith at google.com>
> wrote:
> On 18 February 2015 at 13:04, John McCall <rjmccall at apple.com> wrote:
>
>> > On Feb 18, 2015, at 11:46 AM, Richard Smith <richardsmith at google.com>
>> wrote:
>> > Consider these two cases:
>> >
>> > template<typename T> struct X { struct Y {}; };
>> >
>> > template<template<typename> class U> decltype(X<int>().~U<int>()) f();
>> > template<template<typename> class U>
>> decltype(X<int>::Y().U<int>::Y::~Y()) g();
>> >
>> > Neither of these function templates has a mangling. We get to
>> <unresolved-name> for the destructor name, and find a template template
>> parameter with template args, which we cannot mangle as an
>> <unresolved-type>, and must not mangle as a <simple-id> (because the name
>> of the template template parameter can change between redeclarations).
>> >
>> > Suggested fix: U<int> should be an <unresolved-type>. Replace
>> >
>> >   <unresolved-type> ::= <template-param>
>> >
>> > with
>> >
>> >   <unresolved-type> ::= <template-param> [ <template-args> ]
>> >
>> > ... which results, I think, in these manglings for f<X> and g<X>:
>> >
>> > _Z1fI1XEDTcldtcvS0_IiE_EdnT_IiEEEv
>> > _Z1gI1XEDTcldtcvNS0_IiE1YE_EsrNT_IiE1YEdn1YEEv
>> >
>> > (Clang trunk implements this, but gets the g<X> mangling wrong for
>> other reasons.)
>> >
>> > OK?
>>
>> I had to go and convince myself that an optional dangling production is
>> fine here, but it does look like it can unambiguously and unheroically
>> demangled.  There are several other major productions that use an optional
>> dangling <template-args> like this, most notably <simple-id>; so while this
>> is not my favorite way of designing a mangling, it’s widely precedented in
>> the grammar with this exact production, so the rest of the grammar has been
>> designed to not collide with it.  I did go ahead and verify that it’s
>> unambiguous anyway.  So this looks good to me.
>>
>> Is ~T::T() legal with a template parameter, or does that actually look up
>> “T" in the template argument?
>
>
> It depends on whether the base object has a dependent type. If x's type is
> not dependent, then x.T::~T() looks up the first T within the type and
> names the template parameter if T is not found within the type. If x's type
> is dependent, (the standard is not clear but) lookup within the class is
> deemed to fail and the first T always names the template parameter. In all
> cases, the second T is looked up in the same scope(s) as the first.
>
>
> Okay, thanks.  Do you agree that that’s not something that needs to be
> preserved in the mangling?  It seems like that rule allows us to uniformly
> decide on srT_dnT_ or sd1Tdn1T at parse time in the non-dependent case, and
> whether we’re in the dependent or non-dependent case should always be
> reflected by the mangling of the base expression.
>

Yes, I agree.

If the language required us to do the member-type lookup in the dependent
> case, we’d need a special kind of <unresolved-type> (and even crazier logic
> in function template redeclaration matching, because you wouldn’t be able
> to match templates using different template parameter names when this
> happened…).
>

If the language required that, I'd call it a defect in the specification.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20150218/cbd6b5f3/attachment.html>


More information about the cxx-abi-dev mailing list