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

Reply via email to