Simple test case: unsigned n; void foo (unsigned *p) { n = 4; *p = 0; if (n != 0) abort (); } main () { foo (&n); return 0; } Tested cross-compiling for MIPS, also verified that x86 also has the same problem. attached dump from the fre pass. **** basically n.0_4 should not be assigned the value of 4, since *p can alias it. ;; Function foo (foo) Created value VH.0 for p_3 exp_gen[0] := { } tmp_gen[0] := { p_3 (VH.0) } avail_out[0] := { p_3 (VH.0) } exp_gen[2] := { } tmp_gen[2] := { } avail_out[2] := { p_3 (VH.0) } exp_gen[3] := { } tmp_gen[3] := { } avail_out[3] := { p_3 (VH.0) } exp_gen[4] := { } tmp_gen[4] := { } avail_out[4] := { p_3 (VH.0) } exp_gen[1] := { } tmp_gen[1] := { } avail_out[1] := { } Replaced n with 4 in n.0_4 = n; foo (p) { unsigned int n.0; <bb 2>: n = 4; *p_3 = 0; n.0_4 = 4; ***** if (n.0_4 != 0) goto <L0>; else goto <L1>; <L0>:; abort (); <L1>:; return; }
This worked in "4.3.0 20071127".
Confirmed. Wrong alias info: foo (p) { unsigned int n.0; <bb 2>: # n_2 = V_MUST_DEF <n_1>; n = 4; # NONLOCAL.6_6 = V_MAY_DEF <NONLOCAL.6_5>; *p_3 = 0; # VUSE <n_2>; n.0_4 = n; if (n.0_4 != 0) goto <L0>; else goto <L1>; <L0>:; # VUSE <n_2>; # VUSE <NONLOCAL.6_6>; abort (); <L1>:; return;
4.2.3 is being released now, changing milestones of open bugs to 4.2.4.
*** Bug 35134 has been marked as a duplicate of this bug. ***
Here's another testcase for the same bug, or one closely related to it: #include <stdio.h> unsigned x = 8; unsigned *addr() { return &x; } int main() { x = 4; *addr() = *addr() / 2; printf ("*addr() = %d, x = %d\n", *addr(), x); return 0; } I've determined that both this test case and the original one reported with this issue were fixed on mainline by the commit r119502, this patch: http://gcc.gnu.org/ml/gcc-patches/2006-12/msg00225.html I'm not familiar enough with this code (yet!) to be able to tell whether this was a lurking bug fixed by that patch, or whether it is a lurking bug that was merely obscured by that patch and is still present on mainline.
The problem is that NONLOCAL has to alias all global symbols but does not: # x_2 = V_MUST_DEF <x_1>; x = 4; ... # NONLOCAL.53_13 = V_MAY_DEF <NONLOCAL.53_12>; *D.2057_3 = D.2060_6; That is, during flow insensitive alias computation we'd need to add these, but this makes the whole point of the NONLOCAL tag moot. So getting rid of it is the "fix". But this is way too invasive for 4.2, so 4.2 joins 4.1 in the set of worst-aliasing-bugs-since-ever releases ;)
4.2.4 is being released, changing milestones to 4.2.5.
Closing 4.2 branch, fixed in 4.3.