Bingfeng Mei wrote: > Hello, > > In following code, gcc (mainline version as well as previous versions) > produces wrong code without giving any warning regarding strict aliasing > violation. > > ~/work/trunk-x86/bin/gcc tst.c -O3 -o tst -Wstrict-aliasing=2 > ./tst > barrier1 > Miscompilation > > > If I compile with > ~/work/trunk-x86/bin/gcc tst.c -O3 -o tst -fno-strict-aliasing > ./tst > Barrier1 > > Then it executes correctly. The problem is with LSocketId, which is cast > to a different pointer type. GCC thinks the dereferenced pointer does > not alias with the original variable and goes on to produce wrong code.
Actually, that's not true: the program is undefined, and therefore gcc is not generating wrong code. > This kind of error is really difficult to detect. It would be nice to at > least give a warning. Should I report it as a bug? It warns me: zorro:~ $ gcc --version gcc (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8) Copyright (C) 2008 Free Software Foundation, Inc. zorro:~ $ gcc t.c -O3 -o tst -Wstrict-aliasing=2 t.c: In function 'foo': t.c:20: warning: dereferencing type-punned pointer will break strict-aliasing rules zorro:~ $ ~/gcc/trunk/install/bin/gcc --version gcc (GCC) 4.4.0 20080618 (experimental) Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. zorro:~ $ ~/gcc/trunk/install/bin/gcc t.c -O3 -o tst -Wstrict-aliasing=2 t.c: In function 'foo': t.c:20: warning: dereferencing type-punned pointer will break strict-aliasing rules Andrew. #include <stdio.h> unsigned long long core_id; unsigned long bar(unsigned long extchan, unsigned long* intchan) { *intchan = extchan + 6; return extchan-5; } __attribute__((noinline)) int foo (unsigned long *channelId) { long long LSocketId = *channelId; printf("barrier1\n"); if ((core_id) == 0) { unsigned long destcore = bar(LSocketId, (unsigned long*)&LSocketId); } return LSocketId; } int main(){ unsigned long a = 5; core_id = 0; if(foo(&a) != 11) printf("Miscompilation\n"); }