https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502
--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Harald van Dijk from comment #4) > That's an interesting argument. You may well be right that the original > code, strictly speaking, does not prove that GCC has a bug, but I do think > GCC has a bug nonetheless, and have come up with a different example. > > #include <stdio.h> > #include <string.h> > > int x, y; > > char buf[sizeof (int *)]; > > int main() > { > int *p = &y; > memcpy (buf, &p, sizeof p); > memcpy (&p, buf, sizeof p); > x = 2, y = 1; > if (p == &x + 1) > *p = 2; > else > y = 2; > printf ("x = %d, y = %d\n", x, y); > return 0; > } > > Compiling with -O2, I see "x = 2, y = 1". p has been assigned &y. Whether it > compares equal to &x + 1 is unspecified, but it doesn't change its origins: > p points to y. Therefore, either the assignment to *p should change y, or in > the else branch, the plain assignment to y should change y. Either way, the > correct result is "x = 2, y = 2". > > It seems like GCC is assuming that if p == &x + 1, and &x + 1 != &y, then p > != &y, so the assignment to *p cannot change y. The flaw in that logic is > again the optimisation of &x + 1 != &y to a constant. > > I see the behaviour I describe in versions 4.9.0 and 4.8.2. This program > does print "x = 2, y = 2" in my testing on GCC 4.7.3, but that is because p > == &x + 1 happens to not compare as true in that version. Slightly tweaked > versions of this fail with versions 4.7.3, 4.6.4, 4.5.4 and 4.4.7, but not > 4.3.6. I can't reproduce your findings with any of the specified GCC version nor with any other I tried (I tried on x86_64-linux and x86_64-linux with -m32). The test program always prints "x = 2, y = 2" as expected.