Possible bug in regrename.c???

Marty Hauff marty.hauff@rmit.edu.au
Sun Jul 27 20:14:00 GMT 2003


I'm still new to GCC but I stumbled across the following anomoly whilst trying to make a new port.

The following RTX:
(set  (mem:HI  (reg/v/f:HI 8 r8 [44]) [8 S2 A8])
     (mem:HI  (pre_dec:HI  (mem:HI  (plus:HI  (reg/f:HI 28 r28)
                     (const_int 3 [0x3])) [17 S2 A8])) [8 S2 A8]))

causes set_value_regno() to segfault.

The following stack trace was observed:
__libc_start_main
main
toplev_main
do_compile
compile_file
c_common_parse_file
yyparse
finish_function
c_expand_body
rest_of_compilation
copyprop_hardreg_forward
copyprop_hardreg_forward_1
for_each_rtx
for_each_rtx
for_each_rtx
kill_autoinc_value
set_value_regno

...and the key routine seems to be...

static int
kill_autoinc_value (px, data)
     rtx *px;
     void *data;
{
  rtx x = *px;
  struct value_data *vd = data;

  if (GET_RTX_CLASS (GET_CODE (x)) == 'a')
    {
      x = XEXP (x, 0);
      kill_value (x, vd);
      set_value_regno (REGNO (x), Pmode, vd);
      return -1;
    }
  return 0;
}

It seems that once in kill_autoinc_value(px, data), if px is looking at the 'pre_dec' rtx, then the "if (GET_RTX_CLASS (GET_CODE (x)) == 'a')" test succeeds.  From what I can work out, the code is expecting the next expression in the sequence to only ever be a REG. Since my RTX contains a MEM expression after the PRE_DEC expression, the REGNO(x) macro returns an absurdly large 'register' number and causes vd->e[regno].mode = mode in set_value_regno() to try to reference a value outside the array.  A segfault results.

My first question is "Is the original RTX valid?" and if so "is this a bug?".  I've thought about putting a "if (REG_P(x))" test around set_value_regno() but I'm not sure if this is the answer and what its implications might be.  I'm hoping someone else might have some suggestions.

Thanks
Marty Moose



More information about the Gcc mailing list