digitalmars.D.bugs - [Issue 19101] New: Miscompilation on extern(C++) overloads with D
- d-bugmail puremagic.com (55/57) Jul 19 2018 https://issues.dlang.org/show_bug.cgi?id=19101
https://issues.dlang.org/show_bug.cgi?id=19101 Issue ID: 19101 Summary: Miscompilation on extern(C++) overloads with D types Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: major Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: johanengelen weka.io The following code is miscompiled: ``` // File a.d module a; private struct A { int a; } extern(C++) int foo(T)(T t) { return T.sizeof; } int return4() { A a; return foo(a); } ``` ``` // File b.d module b; import a; private struct A { int[100] a; } void main() { import std.stdio; A a; writeln(foo(a), " =? ", A.sizeof); writeln(return4()); } ``` Compile and run:dmd a.d b.d ./a4 =? 400 4 The problem is that in module a, `foo!(a.A)(a.A)` is mangled the same as module b's `foo!(b.A)(b.A)`, because the extern(C++) function name mangler does not use module name prefix for D types. That is, the mangler is mangling `foo!(A)(A)` instead of `foo!(a.A)(a.A)` and `foo!(b.A)(b.A)`. The two function symbols are merged by the linker (instead of erroring on multiple definition), because the symbols come from templates and merging is required behavior. --> only one of the two _different_ definitions survive, and hence miscompilation results. The fix: use the full D type for mangling. --
Jul 19 2018