Jump to page: 1 2
Thread overview
[Issue 16479] Wrong C++ mangling for template
Sep 09, 2016
Thomas Brix Larsen
Sep 09, 2016
Thomas Brix Larsen
Sep 09, 2016
Thomas Brix Larsen
Oct 26, 2017
Walter Bright
[Issue 16479] Missing substitution while mangling C++ template parameter for functions
Jun 12, 2018
Mathias LANG
Jun 12, 2018
Mathias LANG
Jul 05, 2018
Mathias LANG
Oct 22, 2018
Mathias LANG
Oct 22, 2018
Mathias LANG
Jan 06, 2020
kinke
Jan 06, 2020
Mathias LANG
Aug 04, 2020
Mathias LANG
September 09, 2016
https://issues.dlang.org/show_bug.cgi?id=16479

Thomas Brix Larsen <brix@brix-verden.dk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |C++

--
September 09, 2016
https://issues.dlang.org/show_bug.cgi?id=16479

--- Comment #1 from Thomas Brix Larsen <brix@brix-verden.dk> ---
gcc version 6.2.1 20160830 (GCC)

--
September 09, 2016
https://issues.dlang.org/show_bug.cgi?id=16479

--- Comment #2 from Thomas Brix Larsen <brix@brix-verden.dk> ---
DMD64 D Compiler v2.071.1

--
October 26, 2017
https://issues.dlang.org/show_bug.cgi?id=16479

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |mangling
                 CC|                            |bugzilla@digitalmars.com

--
June 12, 2018
https://issues.dlang.org/show_bug.cgi?id=16479

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pro.mathias.lang@gmail.com
           Hardware|x86_64                      |All
            Summary|Wrong C++ mangling for      |Missing substitution while
                   |template                    |mangling C++ template
                   |                            |parameter for functions

--- Comment #3 from Mathias LANG <pro.mathias.lang@gmail.com> ---
Edited the title to make it a bit clearer. I was hit by this today. DMD does
not respect this part of the spec:
```
When function and member function template instantiations reference the
template parameters in their parameter or result types, the template parameter
number is encoded, with the sequence T_, T0_, ...
```
Source:
https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.template-param

--
June 12, 2018
https://issues.dlang.org/show_bug.cgi?id=16479

--- Comment #4 from Mathias LANG <pro.mathias.lang@gmail.com> ---
This is actually quite a non-trivial problem. Take the following code in C++:
```
#include <array>

template<size_t S, class T>
std::array<T, S>* getArray(const T* data)
{
    auto ret = new std::array<T, S>;
    for (size_t idx = 0; idx < S; ++idx)
        (*ret)[idx] = data[idx];
    return ret;
}

void unused ()
{
    getArray<5, bool>(nullptr);
    getArray<3, int>(nullptr);
    getArray<5, char>(nullptr);
}
```

This gives the following symbols on OSX:
```
0000000000000000 T __Z6unusedv
00000000000000c0 T __Z8getArrayILm3EiEPNSt3__15arrayIT0_XT_EEEPKS2_
0000000000000040 T __Z8getArrayILm5EbEPNSt3__15arrayIT0_XT_EEEPKS2_
0000000000000140 T __Z8getArrayILm5EcEPNSt3__15arrayIT0_XT_EEEPKS2_
                 U __Znwm
```
I mentioned OSX because on Linux, the inlined namespace `__1` might not be
present, thus the symbol (and substitutions) will differ, but the bug is still
there on Linux.

The equivalent D code is as follow:
```
extern(C++, std)
extern (C++, __1) {
    public struct array (T, /*size_t*/ cpp_ulong N)
    {
        private T[N > 0 ? N : 1] __elems_;
    }
}

extern (C++)
array!(T, S)* getArray (cpp_ulong S, T) (const(T)* data);


void main ()
{
    const d1 = [true, false, true, false, true];
    const d2 = [42, 84, 1992];
    const d3 = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

    getArray!5(d1.ptr);
    getArray!3(d2.ptr);
    getArray!6(d3.ptr); // Not 7 on purpose
}
```

This will produce the following symbols with DMD master:
```
nm types.o | grep getArray
     U __Z8getArrayILm3EiEPNSt3__15arrayIiLm3EEEPKi
     U __Z8getArrayILm5EbEPNSt3__15arrayIbLm5EEEPKb
     U __Z8getArrayILm6EcEPNSt3__15arrayIcLm6EEEPKc
```


There are 2 issues here:
- We don't do template parameter substituion, so we end up with the string
"[...]arrayI{i,b,c}Lm{3,5,6}E" to represent `array<{int,bool,char}, {3,4,6}>`
instead of `arrayIT0_XT_E` (using substitution for `getArray`'s template
parameter.
- We don't do substitution for the function parameter. clang++ will use `S2_`
as substitution and g++ `S1_` (because there's no inline namespace) instead of
`{i,b,c}`. It's surprising because substitution does not normally happen for
basic types, but I suppose template parameters are special.

Note that this is non-trivial to solve because of the following case:
```
template <int A, int B>
struct Bar
{
};

template <int A, int B>
Bar<B,A> foo ()
{
    return Bar<B, A>{};
}

void unused ()
{
    foo<1, 2>();
    foo<1, 1>();
}
```

This generates the following symbols:
```
0000000000000030 T __Z3fooILi1ELi1EE3BarIXT0_EXT_EEv
0000000000000020 T __Z3fooILi1ELi2EE3BarIXT0_EXT_EEv
0000000000000000 T __Z6unusedv
```

Which means we cannot solely rely on the value of the template parameters, we have to track which one is used where, but I don't think we have this information in the frontend at the moment...

--
July 05, 2018
https://issues.dlang.org/show_bug.cgi?id=16479

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #5 from Mathias LANG <pro.mathias.lang@gmail.com> ---
PR: https://github.com/dlang/dmd/pull/8455

--
August 02, 2018
https://issues.dlang.org/show_bug.cgi?id=16479

--- Comment #6 from github-bugzilla@puremagic.com ---
Commit pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/beb2a889124e53a6a6cc5218ffc596177b157086 Correct definition of foo15372 in cppa.d

In the C++ file it is defined as `template<typename T> int foo15372(int)`,
but in the D file the argument was the template type.
As template arguments are substituted in mangling,
this was not correct and only compiled thanks to bug 16479

--
October 22, 2018
https://issues.dlang.org/show_bug.cgi?id=16479

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jbc.engelen@gmail.com

--- Comment #7 from Mathias LANG <pro.mathias.lang@gmail.com> ---
*** Issue 15970 has been marked as a duplicate of this issue. ***

--
October 22, 2018
https://issues.dlang.org/show_bug.cgi?id=16479

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timothee.cour2@gmail.com

--- Comment #8 from Mathias LANG <pro.mathias.lang@gmail.com> ---
*** Issue 16944 has been marked as a duplicate of this issue. ***

--
« First   ‹ Prev
1 2