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