www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 22218] New: Dynamic casts across binary boundaries can easily

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

          Issue ID: 22218
           Summary: Dynamic casts across binary boundaries can easily fail
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P1
         Component: druntime
          Assignee: nobody puremagic.com
          Reporter: kinke gmx.net

If there are TypeInfo duplicates in multiple binaries of a process, e.g., from
templates instantiated in multiple binaries, dynamic casts can fail.

E.g., the following code fails with LDC (v1.27) and GDC (v10.3) on Linux,
somehow works with DMD on Linux though, and fails on Windows in general:

```
class C() {}

version (DLL)
{
    version (Windows)
    {
        import core.sys.windows.dll;
        mixin SimpleDllMain;
    }

    pragma(mangle, "foo")
    export Object foo(Object o)
    {
        assert(cast(C!()) o); // <-- fails here
        return new C!();
    }
}
else
{
    T getFunc(T)(const(char)* sym, string thisExePath)
    {
        import core.runtime : Runtime;

        version (Windows)
        {
            import core.sys.windows.winbase : GetProcAddress;
            return cast(T) Runtime.loadLibrary("dynamiccast.dll")
                .GetProcAddress(sym);
        }
        else version (Posix)
        {
            import core.sys.posix.dlfcn : dlsym;
            import core.stdc.string : strrchr;

            auto name = thisExePath ~ '\0';
            const pathlen = strrchr(name.ptr, '/') - name.ptr + 1;
            name = name[0 .. pathlen] ~ "dynamiccast.so";
            return cast(T) Runtime.loadLibrary(name)
                .dlsym(sym);
        }
        else static assert(0);
    }

    void main(string[] args)
    {
        auto c = new C!();

        auto o = getFunc!(Object function(Object))("foo", args[0])(c);
        assert(cast(C!()) o);
    }
}
```

To be built and run like this:

$ dmd -shared dynamiccast.d -version=DLL -ofdynamiccast.so -fPIC
-defaultlib=libphobos2.so
$ dmd dynamiccast.d -ofdynamiccast -fPIC -defaultlib=libphobos2.so
$ ./dynamiccast

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

--
Aug 16 2021