> In fact, it is c-common.c:2289 that does -4 -> (int *)-4 > conversion, but pointer_int_sum is already called with PLUS_EXPR. > build_unary_op unconditionally expands &x[y] to x+y, regardless > of the sign of y. Of course the standard says that they are equal. > But is &x[-1] == x + (int *)4*(int *)-1 ? From this follows that > we have no way to convert this back to &x[-1], as we loose the > sign information by the (int *) cast. > > How do the loop optimizers handle this - negative offsets by relying > on unsigned pointer wrap-around?
Possibly more correct: &x[-1] == (int *)x + (int *)((size_t)4*(int)-1) => &x[-1] == (int *)x - (int *)((size_t)4*(size_t)1) Implying that in general: (unsigned)((unsigned)x * (signed)y) => -((unsigned)x * (unsigned)y) not: +((unsigned)x * (unsigned)(signed)y)