digitalmars.D.bugs - [Issue 22318] New: Calling virtual extern(C++) functions crashing or
- d-bugmail puremagic.com (193/193) Sep 18 2021 https://issues.dlang.org/show_bug.cgi?id=22318
https://issues.dlang.org/show_bug.cgi?id=22318 Issue ID: 22318 Summary: Calling virtual extern(C++) functions crashing or wrong Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: tim.dlang t-online.de While working on issue 22287 I found some other problems with extern(C++) classes with constructors. //////////////// test.d ////////////////// extern(C++): class A { this(int i); ~this(); int i; } interface I { int f() const; } class B : A, I { this(int i); override int f() const; } class D : B { this(int i) { super(i); } override int f() const { return i + 42; } } I createIFromCPP(char type, int i); B createBFromCPP(char type, int i); D createDFromCPP(int i); I createIFromD(char type, int i) { switch (type) { case 'B': return new B(i); case 'D': return new D(i); default: return null; } } B createBFromD(char type, int i) { switch (type) { case 'B': return new B(i); case 'D': return new D(i); default: return null; } } D createDFromD(int i) { return new D(i); } void runCPPTests(); extern(D) void main() { { D d = new D(100); assert(d.f() == 142); // works } { I i = createIFromCPP('D', 100); //assert(i.f() == 142); // fails, because i.f() returns 122 } { B b = createBFromCPP('D', 100); //assert(b.f() == 142); // Segmentation fault } { D d = createDFromCPP(100); //assert(d.f() == 142); // Segmentation fault } runCPPTests(); } //////////////// test.cpp //////////////// #include <assert.h> class A { public: A(int i); virtual ~A(); int i; }; class I { public: virtual int f() const = 0; }; class B : public A, public I { public: B(int i); virtual int f() const; }; class D : public B { public: D(int i); virtual int f() const; }; A::A(int i) : i(i) { } A::~A() { } B::B(int i) : A(i) { } int B::f() const { return i + 22; } I *createIFromCPP(char type, int i) { switch (type) { case 'B': return new B(i); case 'D': return new D(i); default: return 0; } } B *createBFromCPP(char type, int i) { switch (type) { case 'B': return new B(i); case 'D': return new D(i); default: return 0; } } D *createDFromCPP(int i) { D *d = new D(i); return d; } I *createIFromD(char type, int i); B *createBFromD(char type, int i); D *createDFromD(int i); void runCPPTests() { { D *d = new D(100); assert(d->f() == 142); // Segmentation fault } { I *i = createIFromD('D', 100); assert(i->f() == 142); // fails, because i.f() returns 122 } { B *b = createBFromD('D', 100); assert(b->f() == 142); // works } { D *d = createDFromD(100); assert(d->f() == 142); // works } } ////////////////////////////////////////// The issue exists under Linux and Windows. The comments describe the behaviour under Linux x86_64. Sometimes the call results in a crash. Other times it seems to call the function of a parent class. Some calls also work as expected. If the constructors are removed and A.i is set after creating the object, it works as expected. --
Sep 18 2021