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");
}