[Issue 15610] New: extern(C++) multiple inheritance - calling with wrong 'this' ptr
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Mon Jan 25 20:53:26 PST 2016
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 at puremagic.com
Reporter: turkeyman at 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.
--
More information about the Digitalmars-d-bugs
mailing list