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

John McCall rjmccall at apple.com
Thu Feb 19 00:04:44 UTC 2015


> On Feb 18, 2015, at 3:54 PM, Richard Smith <richardsmith at google.com> wrote:
> On 18 February 2015 at 15:35, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>> On Feb 18, 2015, at 1:45 PM, Richard Smith <richardsmith at google.com <mailto:richardsmith at google.com>> wrote:
>> On 18 February 2015 at 13:04, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>> > On Feb 18, 2015, at 11:46 AM, Richard Smith <richardsmith at google.com <mailto: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.

Agreed on that, too.

Okay, I’ll commit this in a week or so if nobody objects.

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20150218/e9db4fb9/attachment.html>


More information about the cxx-abi-dev mailing list