Richard Sandiford <[EMAIL PROTECTED]> writes: > David Daney <[EMAIL PROTECTED]> writes: >> For r131631 bootstrap on mipsel-linux in stage2 I am getting: >> >> [...] >> ../../trunk/gcc/global.c:1020: error: array subscript is above array bounds >> make[3]: *** [global.o] Error 1 >> >> This is new since r131576: >> >> http://gcc.gnu.org/ml/gcc-testresults/2008-01/msg00758.html >> >> The configuration is identical to that successful bootstrap/test > > global.c:1020 is new code that was added during that time. There's > nothing intrinsically wrong with it though. The warning is simply about > something that can't prove is dead code. (I.e. it's another example in > favour of Mark's "the middle end shouldn't warn" thing.) A reduced > testcase is: > > ---------------------------------------------------------------------- > #define BIT(X, B) ((X) < ((B) ? 2 : 4) ? (X) + 4 : ~0U) > > void bar (unsigned int *); > void foo (unsigned int b) > { > unsigned int i, a[4]; > > for (i = 0; BIT (i, b) != ~0U; i++) > a[BIT (i, b) / 32] |= 1U << (BIT (i, b) % 32); > bar (a); > } > ---------------------------------------------------------------------- > > which generates a warning on x86_64-linux-gnu when compiled with -O2 -Wall. > We generate array accesses for a[(i + 4) / 32] and a[~0U / 32] and can't > prove that the latter are never used. > > The attached patch uses the same construct as other E_R_D_R loops > and avoids the warning. I'll test it overnight and install as obvious > if it succeeds.
Bootstrapped & regression-tested on x86_64-linux-gnu. Tested also by building mips64-linux-gnu (with --enable-werror and an equivalent x86_64 CC, as usual). Installed with this change log: gcc/ * global.c (find_reg): Only compute EH_RETURN_DATA_REGNO once per input. > Index: gcc/global.c > =================================================================== > --- gcc/global.c 2008-01-19 23:54:32.000000000 +0000 > +++ gcc/global.c 2008-01-19 23:54:56.000000000 +0000 > @@ -1016,8 +1016,13 @@ find_reg (int num, HARD_REG_SET losers, > if (allocno[num].no_eh_reg) > { > unsigned int j; > - for (j = 0; EH_RETURN_DATA_REGNO (j) != INVALID_REGNUM; j++) > - SET_HARD_REG_BIT (used1, EH_RETURN_DATA_REGNO (j)); > + for (j = 0; ; ++j) > + { > + unsigned int regno = EH_RETURN_DATA_REGNO (j); > + if (regno == INVALID_REGNUM) > + break; > + SET_HARD_REG_BIT (used1, regno); > + } > } > #endif >