Strange bug in egcs-1.1.2 suspected
Joerg Pommnitz
pommnitz@darmstadt.gmd.de
Tue Jun 15 16:53:00 GMT 1999
Once again there came up a thread in linux-kernel
that initially looked very much like an aliasing problem,
however it is with egcs-1.1.2 where the aliasing code is
disabled by default.
Doing some further investigation made the thing more and more
curious. The original example looks like this:
-------------------------------------------------------------
#include <stdio.h>
int
main(int argc, char **argv)
{
struct {char c1, c2, c3, c4;} t;
t.c4 = 0x78; t.c3 = 0x56; t.c2 = 0x34; t.c1 = 0x12;
printf("0x%x\n", *((unsigned long*) &t));
return 0;
}
-------------------------------------------------------------
Remember, the following is compiled with egcs-1.1.2 where Mark's
aliasing framework is disabled by default:
pommnitz ~/alias>gcc aliasorig.c -o aliasorig
pommnitz ~/alias>./aliasorig
0x78563412
pommnitz ~/alias>gcc -O2 aliasorig.c -o aliasorig
pommnitz ~/alias>./aliasorig
0x12
pommnitz ~/alias>gcc -O2 -fno-strict-aliasing aliasorig.c -o aliasorig
pommnitz ~/alias>./aliasorig
0x12
My original aim was to educate somebody on linux-kernel about
the proposed noalias macro. I rewrote the program like this:
-------------------------------------------------------------
#include <stdio.h>
#define noalias(type, ptr) (((union { type __x__; __typeof__(*(ptr)) __y__;} *)(ptr))->__x__)
int
main(int argc, char **argv)
{
struct {char c1, c2, c3, c4;} t;
t.c4 = 0x78; t.c3 = 0x56; t.c2 = 0x34; t.c1 = 0x12;
printf("0x%x\n", noalias (unsigned long, &t));
return 0;
}
-------------------------------------------------------------
The result:
pommnitz ~/alias>gcc -O2 alias2.c -o alias2
pommnitz ~/alias>./alias2
0x12
Still not what we want. OK, next try:
-------------------------------------------------------------
#include <stdio.h>
#define noalias(type, ptr) (((union { type __x__; __typeof__(*(ptr)) __y__;} *)(ptr))->__x__)
int
main(int argc, char **argv)
{
struct {char c1, c2, c3, c4;} t;
t.c4 = 0x78; t.c3 = 0x56; t.c2 = 0x34; t.c1 = 0x12;
printf("0x%x\n", (int) (t.c3));
printf("0x%x\n", noalias (unsigned long, &t));
return 0;
}
-------------------------------------------------------------
The result:
pommnitz ~/alias>gcc -O2 alias.c -o alias
pommnitz ~/alias>./alias
0x0
0x12
Huh??? 0x0 is t.c3 that we just set to 0x56. Something
is really fishy. Further testing revealed, that commenting
out the noalias-printf line restores the correct result for
t.c3.
Can somebody comment on this?
--
Regards
Joerg
GMD-IPSI, Dolivostr. 15, Zimmer 120, D-64293 Darmstadt
+49-6151-869-786 (Phone), -818 (FAX)
More information about the Gcc
mailing list