The following code results in a segmentation fault for DMD in dmd.cppmangle.CppMangleVisitor.getTiNamespace:
alias Identity(T) = T;
extern(C++) Identity!T identity(T)(T val)
{
return Identity!T(val);
}
void main()
{
auto x = identity(5);
}
Comment #1 by moonlightsentinel — 2022-02-04T22:42:30Z
Slightly reduced / modified:
==================================================
template Identity(T)
{
alias T Identity;
}
extern(C++) Identity!T identity(T)()
{
return Identity!T.init;
}
void main()
{
identity!int();
}
==================================================
Up to 2.063 : Success and no output
2.064 to 2.066.0: Segfault and no output
2.067.1 to 2.083.1: Success and no output
Since 2.084.1: Segfault and no output
Comment #2 by pro.mathias.lang — 2022-02-10T04:02:32Z
I see where the issue is. I'm wondering whether this should be rejected by the frontend or not. Essentially we just "see through" the `Identity` template.
However, I don't think that's possible in C++. There might also be some other expectations (what if `Identity` has an `extern(C++)` and namespace declaration?).
Note:
We hit `headOfType`:
https://github.com/dlang/dmd/blob/cefa9ff9d0d68ca21049ffc2d6f08dd1d8c7843c/src/dmd/cppmangle.d#L1376-L1395
with our `res` as `int`, and a few places don't account for types not having Dsymbol.
Comment #3 by ibuclaw — 2022-12-27T10:13:08Z
This issue has the tag "rejects-valid" - but where's the valid C++ code?
If this template has no C++ equivalent, then it should be accepts-invalid, and we issue an error at semantic-time as Matthias has already mentioned.
Comment #4 by tim.dlang — 2022-12-27T12:11:30Z
In my original code this happened for a utility function, which did not come from C++. I used extern(C++): for the whole file, so the utility function also got it, but I have solve it by making this function extern(D).
The following code should be equivalent C++:
==================================================
template <class T>
using Identity = T;
template <class T>
Identity<T> identity(T val)
{
return Identity<T>(val);
}
int main()
{
int x = identity(5);
return 0;
}
==================================================
Making this issue accepts-invalid would also work for me, because templates with alias can probably just be marked as extern(D).
Comment #5 by robert.schadek — 2024-12-13T19:20:46Z