http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51730
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2012-01-02 AssignedTo|unassigned at gcc dot |rguenth at gcc dot gnu.org |gnu.org | Ever Confirmed|0 |1 --- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-01-02 14:01:19 UTC --- (In reply to comment #2) > On Mon, 2 Jan 2012, jakub at gcc dot gnu.org wrote: > > > char digs[] = "0123456789"; > > int xlcbug = 1 / (&(digs + 5)[-2 + (_Bool) 1] == &digs[4] ? 1 : > > -1); > > check. Until http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172958 > > GCC has been accepting this though, and I suppose we don't want to fold > > array > > refs that way when generating code. Would it be possible to fold it that > > way > > (try harder) just when we know we are not going to generate code based on it > > (or when we know we'd error out otherwise)? I know it sounds like an ugly > > As I understand it, the point of that commit was that the conversion of > all array references to pointer arithmetic (losing all information about > signs of indices) was problematic. But it should still be valid to fold a > comparison that way: if the addresses being compared have the same base > object and all offsets are constant integers, a final byte offset for each > address can be computed mod the size of the address space and it's OK to > fold based on comparing those offsets (if the actual, signed offsets > involved overflow anywhere, that would have been execution-time undefined > behavior). That is, I think it would be better to fix this by improving > the folding of address comparisons, rather than by changing how array > references are expanded. I think what changed is that we keep &digs[4] in the IL now, rather than representing it as &digs + 4. So it seems to be some missed folding. Indeed we have (char *) &digs + 4 == &digs[4] I'll look into this.