This code triggers an ICE in gcc-4.3.1 on i686 when compiled with g++: typedef unsigned int ui32; __extension__ typedef unsigned long long int ui64; typedef ui32 __attribute__ ((__may_alias__)) ui32a; typedef ui64 __attribute__ ((__may_alias__)) ui64a; union u_u32 { ui32a v; } __attribute__ ((__may_alias__)); union u_u64 { ui64a v; struct { union u_u32 lo32, hi32; } u; } __attribute__ ((__may_alias__)); void out_long (ui64 longVal) { if ((*(union u_u64 *) &longVal).u.lo32.v < 0x10000000ul) { if ((ui32) ((*(union u_u64 *) &longVal).u.lo32.v) < 0x4000u) { /* do something useful */ } } } longs3.c: In function 'void out_long(ui64)': longs3.c:24: internal compiler error: in build_c_cast, at cp/typeck.c:5631
I get a different internal compiler error: t.cc:24: internal compiler error: canonical types differ for identical types ui32 and ui32a Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
ui32 and ui32a are identical (they are identical in middle-end terms), but ui32 * and ui32a * would not be identical. Sounds weird, but the way may_alias is designed make it so. A 32bit target is required to trigger the ICE.
Patch here: http://gcc.gnu.org/ml/gcc-patches/2008-09/msg01667.html
Subject: Bug 37553 Author: dgregor Date: Tue Oct 14 15:03:51 2008 New Revision: 141111 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141111 Log: 2008-10-14 Douglas Gregor <doug.gregor@gmail.com> PR c++/37553 * tree.c (build_type_attribute_qual_variant): Hash on the unqualified type, and don't overwrite an existing (type_hash_eq): Make the TYPE_NAME of the types significant, to allow distinguishing between wchar_t and its underlying type. This also means that we'll retain a little more typedef information. 2008-10-14 Douglas Gregor <doug.gregor@gmail.com> PR c++/37553 * g++.dg/ext/alias-canon2.C: New. Added: trunk/gcc/testsuite/g++.dg/ext/alias-canon2.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree.c
Fixed on mainline