Bug 18784 – Segfault due to dmd codegen interfacing with C++
Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-04-20T10:24:57Z
Last change time
2019-06-08T21:19:48Z
Keywords
C++, pull, wrong-code
Assigned to
Suleyman Sahmi (سليمان السهمي)
Creator
Atila Neves
Comments
Comment #0 by atila.neves — 2018-04-20T10:24:57Z
The following two files when compiled and linked result in a segfault when using dmd but not ldc2:
d.d:
extern(C++) {
struct Struct {
pragma(mangle, "_ZN6StructC1Ei") this(int);
pragma(mangle, "_ZN6StructC1EOS_") this(Struct*);
this(Struct other) {
this(&other);
}
}
}
void main() {
auto s = Struct(Struct(7));
}
cpp.cpp:
#include <stdio.h>
struct Struct {
Struct(int);
Struct(Struct&&);
};
Struct::Struct(int) {
printf("Oops\n");
}
Struct::Struct(Struct&&) { }
To reproduce:
clang++ -g -c cpp.cpp
dmd -g d.d cpp.o -L-lstdc++ # ldc2 works fine
./d
Preliminary analysis:
Removing the printf from the C++ constructor prevents the segfault. In fact, it seems that the return value of printf is used to deference a pointer. Without the printf, rax has the value it had before and everything works.
The bug only manifests if a temporary is passed directly to the by-value D constructor. Changing `auto s = Struct(Struct(7))` to:
auto tmp = Struct(7);
auto s = Struct(tmp);
Makes the bug disappear.
Using ldc2 works, suggesting that the issue is due to dmd's codegen, especially given what happens to rax as stated above.
This issue is preventing "just works" C++ integration.