[Bug d/97644] FAIL: gdc.dg/gdc204.d due to ICE in finish_thunk

ibuclaw at gdcproject dot org gcc-bugzilla@gcc.gnu.org
Mon Nov 2 12:18:41 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97644

--- Comment #9 from Iain Buclaw <ibuclaw at gdcproject dot org> ---
(In reply to Jan Hubicka from comment #8)
> > Current workaround I'm using locally for the time being is to call
> > thunk_info::process_early_thunks if the particular branch where this ICE
> > happens is hit.
> 
> Why D frontend needs to expand the thunk early and does not rely on
> backend to handle it same way as C++ does?  It would be most practical
> if both was finalizing same way.
> 
> If there is good reason for not doing so and there is no PCH in D
> frontend we could just add argument to expand_thunk to avoid the game o
> putting things into a vector.
> 

Not discounting that I may be doing it wrong.  The call to expand_thunk is
there so that thunks for externally defined methods are generated.

As the backend usually doesn't emit such thunks, a gimple generated thunk is
forced by the frontend.

I have seen linker errors in the past when this was not done, however there
could be some alignment with what C++ does to handle this though.

A simplistic example would be:

    interface I { void foo(); }
    class C : I { void foo(); }

Where a TU local thunk is generated for C.foo.

A more complex example would be when interfacing with C++, where different
methods are implemented half in C++, half in D.

    // C++
    class Base
    {
    public:
        virtual void base() { };
    };

    class Interface
    {
    public:
        virtual int MethodCPP() = 0;
        virtual int MethodD() = 0;
    };

    class Derived : public Base, public Interface
    {
    public:
        int MethodCPP();  // thunk _ZThn8_N7Derived9MethodCPPEv
        int MethodD();    // thunk _ZThn8_N7Derived7MethodDEv
    };

    int Derived::MethodCPP() { return 30; }

    // D
    extern (C++)
    {
        class Base
        {
            void based();
        }

        interface Interface
        {
            int MethodCPP();
            int MethodD();
        }

        class Derived : Base, Interface
        {
            int MethodCPP();  // thunk _DT8_ZN7Derived9MethodCPPEv
            int MethodD()     // thunk _DT8_ZN7Derived7MethodDEv
            {
               return 3;
            }
        }
    }

In the above, g++ and gdc give different global symbol names for the thunks, so
linker errors would occur if they are not emitted.


More information about the Gcc-bugs mailing list