A question about C++ mangling for a complicated template case

Richard Smith richard at metafoo.co.uk
Fri Oct 24 13:23:49 PDT 2014


On Wed, Oct 22, 2014 at 8:32 PM, Jiangning Liu <liujiangning1 at gmail.com>
wrote:

> Hi Richard,
>
> Thanks a lot for your feedback!
>
> Now I can generate an even smaller test case, so I filed a but at
> http://llvm.org/bugs/show_bug.cgi?id=21351.
>
> The small test case is like
>
> {code}
> emplate <int dim> class AA { public: AA(){} };
>
>
> class BB
> {
> public:
>     template <template<int> class C>
>     static C<3> fin (const C<3> &);
> };
>
> AA<3> f(const AA<3> &dof)
> {
>     return BB::fin(dof);
> }
> {code}
>
> I'm not familiar with clang, so what is the term or symbol T0_IXT_EE ? I
> can't find it in clang source code. Can you explain more? I want to get
> this bug fixed, and it is blocking my benchmarking work.
>

This is part of the Itanium C++ ABI's name mangling scheme. T0_ means "the
second template parameter", I ... E denotes a template argument list, X ...
E denotes a template argument expression, and T_ means "the first template
parameter". So this whole thing means C<n> (where C is the second template
parameter and n is the first).

See http://mentorembedded.github.io/cxx-abi/abi.html#mangling for the gory
details.

A patch that fixes the bug is out for review. =)


> Thanks,
> -Jiangning
>
> 2014-10-23 5:20 GMT+08:00 Richard Smith <richard at metafoo.co.uk>:
>
>> On Wed, Oct 22, 2014 at 3:58 AM, Jiangning Liu <liujiangning1 at gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I have a question about C++ name mangling.
>>>
>>> For the following small program (I failed to get it further minimized),
>>> clang++ and g++ generate different symbols for function fin introduced by
>>> the last specialization statement.
>>>
>>> clang++: AA<3>::aa BB::fin<3, AA>(AA const&)
>>> g++:        AA<3>::aa BB::fin<3, AA>(AA<3> const&)
>>>
>>
>> Demangled names are not useful when talking about mangling differences.
>> The mangled names are:
>>
>>   _ZN2BB3finILi3E2AAEENT0_IXT_EE2aaERKS2_ (from clang)
>>   _ZN2BB3finILi3E2AAEENT0_IXT_EE2aaERKS3_ (from gcc)
>>
>> GCC's mangling appears to be correct here (modulo a bug in the ABI that
>> gives a mangling to an empty <prefix>). S2_ refers to T0_ from the
>> nested-name-specifier in the return type; S3_ refers to T0_IXT_EE, which is
>> what we want in the parameter's type.
>>
>>
>>> If I change the return type of fin to be void, I can see the argument
>>> AA<3> can be correctly generated for clang++.
>>>
>>> {code}
>>> template <int dim>
>>>
>>> class AA
>>> {
>>>     template <class DH> struct Iter;
>>>
>>>     template <template <int> class DH>
>>>     struct Iter<DH<3> >
>>>     {
>>>         typedef DH<3> AA_type;
>>>     };
>>>
>>>     typedef Iter<AA<dim> > IteratorSelector;
>>> public:
>>>     typedef typename IteratorSelector::AA_type aa;
>>> };
>>>
>>> class BB
>>> {
>>>     template <int dim, template<int> class C>
>>>     static typename C<dim>::aa fin (const C<dim> &container);
>>>
>>>     template <int dim>
>>>     static void pp (const AA<dim>& dof)
>>>     {
>>>         typename AA<dim>::aa temp = fin (dof);
>>>     }
>>> };
>>>
>>> template void BB::pp<3> (const AA<3>&);
>>> {code}
>>>
>>> So anybody know why?
>>>
>>> This problem will cause failure of linking object files generated by
>>> clang++ and g++ separately, and potentially introduce run-time bugs.
>>>
>>> Thanks,
>>> -Jiangning
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141024/1321887e/attachment.html>


More information about the cfe-commits mailing list