www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19267] New: extern(C++) cast from interface to child class

https://issues.dlang.org/show_bug.cgi?id=19267

          Issue ID: 19267
           Summary: extern(C++) cast from interface to child class returns
                    wrong pointer value
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: critical
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: atila.neves gmail.com

The code at the end with extern(C++) prints:

fooImpl   0x7fa6503c1000
foo       0x7fa6503c1008

foo       0x7fa6503c1008
fooImpl   0x7fa6503c1008


If the interface and class are extern(D) it (correctly) prints:

fooImpl   0x7fa6503c1000
foo       0x7fa6503c1008

foo       0x7fa6503c1008
fooImpl   0x7fa6503c1000


Casting from the class to the interface works in both cases and adds 8 bytes to
the pointer. Casting back from interface to the class only works for extern(D)
and fails for extern(C++): there's no way to get the original pointer back
except for manually subtracting 8 bytes.

Code to reproduce:



import core.stdc.stdio: printf;

extern(C++) interface Foo {
    int foo();
}

extern(C++) class FooImpl: Foo {
    override int foo() { return 42; }
}

void main() {
    auto fooImpl = new FooImpl;
    printf("fooImpl   %p\n", fooImpl);

    Foo foo = fooImpl;
    printf("foo       %p\n", foo);

    printf("\n");
    takingFoo(foo);
}


void takingFoo(Foo foo) {
    printf("foo       %p\n", foo);
    FooImpl fooImpl = cast(FooImpl) foo;  // oops
    printf("fooImpl   %p\n", fooImpl);

}

--
Sep 26 2018