digitalmars.D.bugs - [Issue 15610] New: extern(C++) multiple inheritance - calling with
- via Digitalmars-d-bugs (48/48) Jan 25 2016 https://issues.dlang.org/show_bug.cgi?id=15610
https://issues.dlang.org/show_bug.cgi?id=15610 Issue ID: 15610 Summary: extern(C++) multiple inheritance - calling with wrong 'this' ptr Product: D Version: D2 Hardware: x86_64 OS: Windows Status: NEW Severity: blocker Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: turkeyman gmail.com I'm seeing a case where 'this' being passed to a C++ function is wrong. C++ multiple-inheritance calls expect that 'this' pointers are adjusted by the offset of the base class. Something like this: extern(C++) class Base { ~this() {} size_t i; } // Base is 16 bytes extern(C++) interface I { void f(); } extern(C++) class C : Base, I { final override void f(); } C is: { _vtbl, i, _I_vtbl (this+16h) } void code(C c) { // crash: c.f(); passes this = 'c' to f(), but C++ expects 'c + C._I_vtbl.offsetof' } In this example, I have a class instance 'c', and I'm calling 'f' (introduced by the interface), which is marked final, so D is able to perform a static call to the C++ function with no vtable lookup. I have managed to get this to link, and D does call the correct C++ function, but D doesn't seem to adjust the 'this' pointer correctly for the call. The C++ function 'f' expects that 'this' is an I pointer (not a C pointer), which is offset by sizeof(Base) from the start of C, but D just passes 'this' unaltered. The result is that within C::f(), the C++ code expects that 'C' is at 'this-16h', and everything is 16 bytes out of phase leading to a prompt crash. TL;DR: Calling of multiple-inherited C++ interfaces requires adjustment of the 'this' pointer before making the call. --
Jan 25 2016