On Thu, Jul 2, 2009 at 3:21 PM, Andrew Stubbs<a...@codesourcery.com> wrote: > Hi all, > > I'm fairly sure I have found an aliasing bug in GCC, although I could be > wrong. I've reproduced it in both 4.4 and mainline. > > Consider this testcase, aliasing.c: > > extern void *foo; > > extern inline short ** > f1 (void) > { > union > { > void **v; > short **s; > } u; > > u.v = (&foo); > if (*u.s == 0) *u.s = (short *)42; > return u.s; > } > > const short *a, *b; > > int > f () > { > a = *f1(); > b = *f1(); > } > > The (not very useful) testcase initialises foo to 42, if necessary, and then > sets both 'a' and 'b' to equal foo. There should be no way that 'a' and 'b' > can ever be set to zero. > > Compile the code as follows: > > sh-linux-gnu-gcc -c aliasing.c -O2 -fdump-tree-all > > The dump file aliasing.c.133t.optimized (the last tree dump) then contains: > > f () > { > void * foo.3; > short int * D.1982; > short int * * D.1973; > > <bb 2>: > foo.3_10 = foo; > D.1982_26 = (short int *) foo.3_10; > if (D.1982_26 == 0B) > goto <bb 3>; > else > goto <bb 5>; > > <bb 3>: > D.1973_13 = (short int * *) &foo; > *D.1973_13 = 42B; > a = 0B; > > <bb 4>: > b = D.1982_26; > return; > > <bb 5>: > a = D.1982_26; > goto <bb 4>; > > } > > This is the state of the code after the tree optimisations. Both 'a' and 'b' > are set to the initial value of foo, before it was initialised. Not only > that, but 'a' is explicitly set to zero. > > This problem goes away if -fno-strict-aliasing is used. > > Is this a compiler bug? Or have I got something wrong in my code?
You are writing to memory of type void * via an lvalue of type short *. Richard. > Thanks > > Andrew >