[Issue 19101] New: Miscompilation on extern(C++) overloads with D types
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Thu Jul 19 19:17:43 UTC 2018
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 at puremagic.com
Reporter: johanengelen at 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.
--
More information about the Digitalmars-d-bugs
mailing list