Hello,

while porting FICL, I noticed an aliasing bug which manifests (at least)
with gcc 4.4.2 and 4.4.3 when strict-aliasing is enabled. The root cause is

#define LVALUEtoCELL(v) (*(CELL *)&v)

in sys/boot/ficl/ficl.h. CELL is a union:

typedef union _cell
{
    FICL_INT i;
    FICL_UNS u;
[...]
    void *p;
    void (*fn)(void);
} CELL;

If you compile the attached C file with gcc-4.4.3 and -O3, all stores to
i are optimized out and the result is bogus. A ficl built with this gcc
is inoperable.

Giving the union the may_alias attribute works around this, but is GCC
specific (patch is attached). Just using ((CELL)v) does not work without
casting all over the place or extending the union.

Regards, Julian
-- 
"Actually I made up the term 'object-oriented', and I can tell you I
did not have C++ in mind." - Alan Kay (OOPSLA 1997 Keynote)
--- ficl.h	2010-02-15 18:46:27.020120933 +0100
+++ /home/julian/src/nova/ficl/ficl.h	2010-02-15 18:16:32.370312051 +0100
@@ -269,13 +269,17 @@
 #endif
     void *p;
     void (*fn)(void);
-} CELL;
+} __attribute__((may_alias)) CELL;
 
 /*
 ** LVALUEtoCELL does a little pointer trickery to cast any CELL sized
 ** lvalue (informal definition: an expression whose result has an
 ** address) to CELL. Remember that constants and casts are NOT
 ** themselves lvalues!
+**
+** XXX This only works as long as the strict-aliasing rule is
+** circumvented (see attribute above). Otherwise GCC >4.4 will
+** silently throw away v and just put garbage into the CELL.
 */
 #define LVALUEtoCELL(v) (*(CELL *)&v)
 

Attachment: pgpxe1pn0ZTVW.pgp
Description: PGP signature

Reply via email to