March 11, 2021
https://issues.dlang.org/show_bug.cgi?id=21690

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |b2.temp@gmx.com

--- Comment #11 from Basile-z <b2.temp@gmx.com> ---
Very hypothetically, let's say that if "super" calls are supported in C++ classes then this means that maybe the super virtual table is stored somewhere. If so then full dynamic casts would be possible.

Someone needs to study a bit more the ABI of extern(C++) classes in D.
Then maybe a dedicated dyncast() could be added to druntime.

--
June 07, 2021
https://issues.dlang.org/show_bug.cgi?id=21690

--- Comment #12 from Basile-z <b2.temp@gmx.com> ---
(In reply to Basile-z from comment #11)
> Very hypothetically, let's say that if "super" calls are supported in C++ classes then this means that maybe the super virtual table is stored somewhere. If so then full dynamic casts would be possible.
> 

this supplemental comment was BS. Obviously `super` does not use the vtable.

> Someone needs to study a bit more the ABI of extern(C++) classes in D.
> Then maybe a dedicated dyncast() could be added to druntime.

--
June 07, 2021
https://issues.dlang.org/show_bug.cgi?id=21690

--- Comment #13 from Basile-z <b2.temp@gmx.com> ---
(In reply to thomas.bockman from comment #10)
> However, it seems a little too unpredictable and limited to be worth implementing in the compiler itself, given that kinke mentioned earlier that two instances of the same class may still end up pointing to different vtable addresses if they were instantiated on different sides of the language barrier:
> 
> (kinke from comment #1)
> > But then again, when we are confronted with some C++ class ref, we have no idea whether it was instantiated on the D side or C++ side and so which vtable its vptr points to.

Major problem indeed.

--
June 04, 2022
https://issues.dlang.org/show_bug.cgi?id=21690

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
                 CC|                            |bugzilla@digitalmars.com

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=21690

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--
June 01, 2023
https://issues.dlang.org/show_bug.cgi?id=21690

Bolpat <qs.il.paperinik@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |qs.il.paperinik@gmail.com

--- Comment #14 from Bolpat <qs.il.paperinik@gmail.com> ---
(In reply to kinke from comment #1)
> So while getting proper dynamic casts working is probably quite hard, we
> could probably disallow downcasts like this and require an explicit static
> cast (`cast(CC) cast(void*) ca`)?

In C++ terminology at least, this isn’t a `static_cast`, but a `reinterpret_cast`. It works when you only have single inheritance (counting interfaces as inheritance as well). As soon as any form of multiple inheritance (including interfaces) enters the picture, `cast(void*)` won’t do what you want. There are simple, but relevant, pointer value adjustments at play.

Example:
```d
import std.stdio;
extern(C++) abstract class B { int x; abstract void f(); }
extern(C++) interface I { void g(); }
extern(C++) class D : B, I
{
    override void f() => writeln("f");
    override void g() => writeln("g");
}

void main()
{
    D d = new D;
    void* bptr = cast(void*) cast(B) d;
    void* iptr = cast(void*) cast(I) d;
    assert(bptr !is iptr); // passes

    void* vptr = cast(void*) d;
    B b = cast(B) vptr;
    I i = cast(I) vptr;
    b.f(); // prints f as expected
    i.g(); // should print g, on run.dlang.org, prints f as well
}
```
The `extern(C++)` has little to do with it; with `extern(D)` the problems
persist.

As far as I know, for class handles, it’s syntactically impossible to express a
C++ `static_cast` in D; it’s a `dynamic_cast` or – if you go via `void*` – it’s
a `reinterpret_cast`. Of course, a derived-to-base `dynamic_cast` can be
optimized to be a `static_cast`, but there’s no way to tell the compiler: I
*know* this base-class object is in fact a derived object, so adjust the
pointer accordingly (and don’t check TypeInfo or whatever and give me UB if I’m
wrong).
A simple solution would be to introduce `static cast(Type) UnaryExpression` for
that. It would be valid only if `Type` and the type of `UnaryExpression` are
both a class or interface type, which have a unique inheritance relationship.

--
June 03, 2023
https://issues.dlang.org/show_bug.cgi?id=21690

--- Comment #15 from Dlang Bot <dlang-bot@dlang.rocks> ---
@ntrel created dlang/dmd pull request #15293 "Disallow dynamic cast on extern(C++) class" mentioning this issue:

- Disallow dynamic cast on extern(C++) class

  See Issue 21690 - Unable to dynamic cast extern(C++) classes.

https://github.com/dlang/dmd/pull/15293

--
June 03, 2023
https://issues.dlang.org/show_bug.cgi?id=21690

Nick Treleaven <nick@geany.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=23957

--
1 2
Next ›   Last »