[cxx-abi-dev] Mangling of function-to-pointer conversion

Jason Merrill jason at redhat.com
Thu Jun 17 19:41:21 UTC 2010


On 06/09/2010 12:55 PM, Mike Herrick wrote:
> While working on SFINAE mangling, I ran across this issue with an implicit function-to-pointer conversion.  Given:
>
> $ cat test.cpp
> template<class T>  struct A {
>    template<void (*PF)()>  struct B {};
> };
> template<void (*PF)()>  struct B {};
> void ff();
> template<class T>  B<&ff>  f1(T);
> template<class T>  B<ff>   f2(T);
> template<class T>  typename A<T>::template B<&ff>  f3(T);
> template<class T>  typename A<T>::template B<ff>   f4(T);
> int main() {
>    f1(1);
>    f2(1);
>    f3(1);
>    f4(1);
> }
> $ g++450 -fabi-version=0 -c test.cpp&&  nm -u test.o
>                 U _Z2f1IiE1BIXadL_Z2ffvEEET_
>                 U _Z2f2IiE1BIXadL_Z2ffvEEET_
>                 U _Z2f3IiEN1AIT_E1BIXadL_Z2ffvEEEES1_
>                 U _Z2f4IiEN1AIT_E1BIL_Z2ffvEEES1_
> $ eccp -c test.cpp&&  nm -u test.o
>                 U _Z2f1IiE1BIXadL_Z2ffvEEET_
>                 U _Z2f2IiE1BIXadL_Z2ffvEEET_
>                 U _Z2f3IiEN1AIT_E1BIXadL_Z2ffvEEEES1_
>                 U _Z2f4IiEN1AIT_E1BIXadL_Z2ffvEEEES1_
> $ clang++ -c test.cpp&&  nm -u test.o
> __Z2f1IiE1BILZ2ffvEET_
> __Z2f2IiE1BILZ2ffvEET_
> __Z2f3IiEN1AIT_E1BIXadL_Z2ffvEEEES1_
> __Z2f4IiEN1AIT_E1BIXL_Z2ffvEEEES1_
>
> When ff is used as a nontype template parameter in f2, both g++ and EDG add an "ad" to represent the implied function-to-pointer conversion.  However, that's not the case in f4 where g++ doesn't add the "ad".
>
> The ABI spec says (5.1.5): "Except for the parentheses, therefore, it [the mangled expression encoding] represents the source token stream".  That would seem to indicate that the mangling for f2 is wrong (as is EDG's mangling for f4).
>
> Does anyone know the logic behind adding the "ad" in the mangled name for f2 (and whether or not that same logic applies to f4)?

Presumably it's there because of the conversion of the template argument 
to match the template parameter; this doesn't apply to f4 because in f4 
we don't know what the template parameters of A<T>::B are.

I don't have a particular opinion about whether or not adding the "ad" 
is a good thing, but given that G++ has put it there since 3.4 (3.0-3.3 
crashed on this testcase) I'd rather not change it.

> Curiously, g++ doesn't add the "ad" in dependent cases:
>
> template<class T>  auto f5(T p1) ->  decltype(p1(f));

Again, there is no conversion to match a target type in this case.

Jason



More information about the cxx-abi-dev mailing list