Hi!
I'd never been able to build gpc on any alpha host: gpc1 would ICE while building a couple of files within gcc/p/rts, for example, error.pas. Tonight, I decided to try to track the problem down.
First, I tried to come up with a minimal testcase that reproduced the problem:
The problem was that, while expanding the ARRAY_REF, get_inner_reference() would build a MULT_EXPR with type ssizetype (SImode), but the index type was sizetype (DImode). Since there was no intervening convert(), expand_mult would call copy_to_mode_reg(SImode, a_DImode_register), that would abort().
The problem was that ssizetype was not being properly initialized so as to match sizetype, and it's fixed with the following patch, that matches the corresponding section of c-decl.c as of gcc 2.95.2 and current CVS:
I'm Cc:ing the gcc mailing list because I thought we could have helped avoid this problem:
- we could arrange that sizetype is no longer an lvalue, so that only set_sizetype would assign to it, and misuses would get a compile-time error instead of a run-time crash only on platforms with ssize_t == long == DImode and int == SImode.
- in the code snippet below, from expr.c:get_inner_reference(), we could explicitly convert index to ssizetype. AFAICT, fold would drop the conversion if it found it needless.
/* Either the bit offset calculated above is not constant, or it overflowed. In either case, redo the multiplication against the size in units. This is especially important in the non-constant case to avoid a division at runtime. */ xindex = fold (build (MULT_EXPR, ssizetype, index, convert (ssizetype, TYPE_SIZE_UNIT (TREE_TYPE (exp)))));