https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106977
--- Comment #12 from ibuclaw at gcc dot gnu.org ---
Looks like a bad mismatch between C++ and D.
When C++ calls the method, it pushes one register. When D calls it, pushes
two.
Looks like the method itself returns the result in 2 registers as well - or
maybe uses return slot optimization.
---
// C++ Caller code
#include "tree.h"
#include "dmd/dsymbol.h"
#include "dmd/aggregate.h"
void
set_visibility_for_decl (tree node, Dsymbol *sym)
{
Visibility visibility = sym->visible ();
// C++ Caller asm
pushl %ebx
subl $20, %esp
.loc 1 2561 1
movl 32(%esp), %eax
movl 28(%esp), %ebx
.loc 1 2562 40
movl (%eax), %edx
pushl %eax
call *104(%edx)
// D Caller code
import dmd.dsymbol;
import dmd.aggregate;
import dmd.gluelayer;
extern(C++)
void
set_visibility_for_decl (tree_node* node, Dsymbol sym)
{
Visibility visibility = sym.visible();
}
// D Caller asm
subl $28, %esp
.loc 1 5 1
movl 36(%esp), %eax
.loc 1 8 27
leal 8(%esp), %ecx
subl $8, %esp
movl (%eax), %edx
pushl %eax
pushl %ecx
call *104(%edx)
// D Callee code
override final Visibility visible() pure nothrow @nogc @safe
{
return visibility;
}
// D Callee asm
movl 8(%esp), %edx
movl 4(%esp), %eax
.loc 1 789 9
movl 208(%edx), %ecx
movl 212(%edx), %edx
movl %ecx, (%eax)
movl %edx, 4(%eax)
.loc 1 790 5
ret $4