Weird GIMPLE by gccgo

Hi!

I've been playing with gccgo / dragonegg, trying to get it to compile
Go reliably. One of the problems I am currently facing is that when
compiling Go, GCC tends to generate GIMPLE calls that don't have the
correct type (or so it seems to me :slight_smile: ). For instance, when compiling
ddd.go from the Go testsuite, I get this:

    i.91 = i;
    D.785 = i.91.__methods;
    D.786 = D.785->Sum;
    D.787 = __go_new_nopointers (16);
    MEM[(int[4] *)D.787][0] = 2;
    MEM[(int[4] *)D.787][1] = 3;
    MEM[(int[4] *)D.787][2] = 5;
    MEM[(int[4] *)D.787][3] = 7;
    D.788.__values = D.787;
    D.788.__count = 4;
    D.788.__capacity = 4;
    D.789 = i.91.__object;
    x = D.786 (D.789, D.788); // [1]
    if (x != 17) goto <D.790>; else goto <D.791>;

Here `i' is

  struct
{
  struct
  {
    const struct * __type_descriptor;
    int (*<Td6>) (struct ) Sum;
  } * __methods;
  void * __object;
} i;

Since `Sum' takes only one argument and is called with two in [1], [1]
trips an assertion when dragonegg tries to convert it. I'm not
familiar with GIMPLE -- is this normal? How can this be fixed? The
call does not seem to be passing a static chain (at least from what I
could make out, dragonegg handles the gimple_call_chain case anyway).

Thank you for your time!

Hi Sanjoy,

I've been playing with gccgo / dragonegg, trying to get it to compile
Go reliably. One of the problems I am currently facing is that when
compiling Go, GCC tends to generate GIMPLE calls that don't have the
correct type (or so it seems to me :slight_smile: ). For instance, when compiling
ddd.go from the Go testsuite, I get this:

this is probably a Go bug. The GCC Fortran front-end also likes to produce
crazy calls like this. They are probably unintentional but the front-end
authors never noticed because GCC is very forgiving of this kind of thing: it
just sticks the extra parameter in whatever register it goes in and performs
the call. Since the callee isn't expecting an extra parameter it just ignores
that register and no harm is done. Dragonegg is much less forgiving as you
noticed, but in the long term it will probably need to become as forgiving as
GCC. To work around it you might want to try setting flag_functions_from_args
to true for Go, like for Fortran. That enables a hacky imitation of GCC's
behaviour which works OK for languages without varargs functions.

Ciao, Duncan.