www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19101] New: Miscompilation on extern(C++) overloads with D

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
 ./a
4 =? 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