[cxx-abi-dev] N4198 and mangling for member pointer template arguments

John McCall rjmccall at apple.com
Mon Dec 1 20:02:06 UTC 2014


> On Nov 25, 2014, at 6:13 PM, Richard Smith <richardsmith at google.com> wrote:
> 
> N4198 (accepted at Urbana) makes it possible for a template parameter of type T U::* to have a template argument of type T V::*, where V is a base class of U or vice versa. A naive attempt to apply the existing ABI rules leads to mangling collisions in cases like this:
> 
> struct A { int n; };
> struct B : A {};
> template<int A::*> void f() {}
> template<int B::*> void f() {}
> void g() {
>   constexpr int A::*p = &A::n;
>   constexpr int B::*q = p;
>   f<p>();
>   f<q>();
> }
> 
> (Here, a naive approach would use XadL_ZN1A1nEEE as the template argument value in both calls.)
> 
> In order to resolve this, I suggest we introduce a new mangling for the case of a member pointer template argument where the class containing the member is different from the class in the template parameter. The minimal information we'll need to include is the class in the template parameter and a designator if the base class is a repeated base class.
> 
> One approach would be to use
> 
>   sc <type> ad L<member>E
> 
> and to explicitly include the final type plus those intermediate types that introduce multiple inheritance from the base class (that is, just enough to uniquely identify the path).
> 
> Another would be to introduce a new mangling that incorporates the final type and an offset or discriminator.

Do we have the same problem for references and pointers to base subobjects?  Okay, I see that the answer is “no”, but only because you kept that restriction in N4198.  I think we can assume that that’s not permanent.

I like the idea of using (possibly invented) static_casts; it’s not optimally compact, but it at least theoretically works with existing demanglers.  Have you checked to see if it actually works?

I agree with only including those intermediate steps necessary to uniquely determine the path.

We’d have to specify in what dependent situations we include the path.  “Never” is the easiest answer, so that in
  template <class T, int T::*member> void foo(decltype(T() + temp<&A::baz>());
we’d mangle &A::baz without a path clarification even if we could type-check "temp<&A::baz>()” at template definition time.

John.


More information about the cxx-abi-dev mailing list