March 29, 2023
https://issues.dlang.org/show_bug.cgi?id=23814

          Issue ID: 23814
           Summary: [Codegen] Calling member function of extern(C++) class
                    with multiple inheritance doesn't preserve the EBX
                    register in some cases
           Product: D
           Version: D2
          Hardware: x86
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: naydef@abv.bg

I'm testing with the following code (although it doesn't seem to use this register every time for bug to manifest):

------------------------------
extern(C++) interface BaseInterface1
{
public:
    const(char)* func1();
    const(char)* func2();
}

extern(C++) abstract class BaseInterface2
{
public:
    const(char)* func3() {return "func3";}
    const(char)* func4() {return "func4";}
}

extern(C++) class MainClass : BaseInterface2, BaseInterface1
{
    override const(char)* func1() {return "func1_overriden";}
    override const(char)* func2() {return "func2_overriden";}
    override const(char)* func3() {return "func3_overriden";}
    override const(char)* func4() {return "func4_overriden";}
}


void main()
{
    auto cls = new MainClass();

    import core.stdc.stdio;
    printf("We'll now call func4");

    cls.func2();
}
------------------------------

The call to func2(), which will be a virtual call, would redirect execution to
something like that(from IDA):

sub     [esp+arg_0], 4
call    $+5
pop     ebx ; EBX value not saved...
add ebx, 0x1234
jmp __somememberfunction

--