http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49330
--- Comment #8 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-06-10
09:59:06 UTC ---
(In reply to comment #7)
> The alias.c machinery is clearly based on the fundamental assumption of
> pointer
> arithmetics, i.e. that you aren't allowed to compute a difference unless both
> pointers point to the same enclosing object. The testcase is a nice attempt
> at
> smuggling the violation of this rule behind a uintptr_t based manipulation.
>
> Not clear what to do IMO. Richard is proposing to leverage the escape sites:
>
> px_1 = (uintptr_t) &x;
> py_2 = (uintptr_t) &y;
>
> but this will pessimize. Ideally we should leverage the one problematic line:
>
> p.2_6 = (int *) p_5;
>
> which creates the pointer out of the integer, but it has already disappeared
> in
> the very first RTL representation.
Creating that pointer is perfectly valid - you are allowed to cast a
pointer to an uintptr_t and back, which is what the code does (in some
obfuscated way of course).
p.2_6 = (int *) ((uintptr_t) &y + ((uintptr_t) &x - (uintptr_t) &y)))
which is, as is trivially obvious, (int *) (uintptr_t) &x.
Consider
int foo(uintptr_t a)
{
uintptr_t px = (uintptr_t) &x;
uintptr_t py = a;
volatile uintptr_t d = px - py;
uintptr_t p = py + d;
x = 1;
*(int *) p = 2;
return x;
}
int main() { foo(&y); }
which is equivalent.