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)
pgpxe1pn0ZTVW.pgp
Description: PGP signature