------- Comment #2 from jakub at gcc dot gnu dot org 2008-01-23 10:59 ------- This is actually a big can of worms. may_alias causes a distinct type code to be created. For mangling I've tried: --- mangle.c.jj128 2007-10-08 10:44:57.000000000 +0200 +++ mangle.c 2008-01-23 11:11:12.000000000 +0100 @@ -1,5 +1,5 @@ /* Name mangling for the 3.0 C++ ABI. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. Written by Alex Samuel <[EMAIL PROTECTED]>
@@ -1768,6 +1768,8 @@ write_CV_qualifiers_for_type (const tree static void write_builtin_type (tree type) { + tree name = NULL; + switch (TREE_CODE (type)) { case VOID_TYPE: @@ -1781,7 +1783,9 @@ write_builtin_type (tree type) case INTEGER_TYPE: /* TYPE may still be wchar_t, since that isn't in integer_type_nodes. */ - if (type == wchar_type_node) + if (TYPE_NAME (type)) + name = DECL_NAME (TYPE_NAME (type)); + if (name && name == DECL_NAME (TYPE_NAME (wchar_type_node))) write_char ('w'); else if (TYPE_FOR_JAVA (type)) write_java_integer_type_codes (type); @@ -1792,7 +1796,7 @@ write_builtin_type (tree type) it in the array of these nodes. */ iagain: for (itk = 0; itk < itk_none; ++itk) - if (type == integer_types[itk]) + if (name && name == DECL_NAME (TYPE_NAME (integer_types[itk]))) { /* Print the corresponding single-letter code. */ write_char (integer_type_codes[itk]); @@ -1837,13 +1841,15 @@ write_builtin_type (tree type) break; case REAL_TYPE: - if (type == float_type_node - || type == java_float_type_node) + gcc_assert (TYPE_NAME (type)); + name = DECL_NAME (TYPE_NAME (type)); + if (name == DECL_NAME (TYPE_NAME (float_type_node)) + || name == DECL_NAME (TYPE_NAME (java_float_type_node))) write_char ('f'); - else if (type == double_type_node - || type == java_double_type_node) + else if (name == DECL_NAME (TYPE_NAME (double_type_node)) + || name == DECL_NAME (TYPE_NAME (java_double_type_node))) write_char ('d'); - else if (type == long_double_type_node) + else if (name == DECL_NAME (TYPE_NAME (long_double_type_node))) write_char ('e'); else gcc_unreachable (); i.e. compare type names rather than types, because for distinct type copies TYPE_MAIN_VARIANT doesn't point us to the original builtin type. But there are still issues, say on: // PR c++/34936 // { dg-do compile } typedef float f __attribute ((may_alias)); typedef double d __attribute ((may_alias)); typedef long double e __attribute ((may_alias)); typedef char c __attribute ((may_alias)); typedef unsigned char uc __attribute ((may_alias)); typedef signed char sc __attribute ((may_alias)); typedef short int s __attribute ((may_alias)); typedef unsigned int u __attribute ((may_alias)); typedef long int l __attribute ((may_alias)); typedef long long int ll __attribute ((may_alias)); typedef wchar_t w __attribute ((may_alias)); typedef bool b __attribute ((may_alias)); void foo1 (char, unsigned char, signed char, short int, unsigned int, long int, long long int, wchar_t, bool) { } void bar1 (c, uc, sc, s, u, l, ll, w, b) { } void foo2 (float, double, long double) { } void bar2 (f, d, e) { } which IMHO should be mangled the same between foo and bar, after s/bar/foo/g but e.g. sc is mangled differently from signed char and ll from long long int. Here the problem is type hashing which disregards type names, so throws typedef char __attribute__((may_alias)) into the same equivalence set as typedef signed char __attribute__((may_alias)). Or consider: // PR c++/34936 // { dg-do compile } typedef float f __attribute ((may_alias)); typedef double d __attribute ((may_alias)); typedef long double e __attribute ((may_alias)); typedef char c __attribute ((may_alias)); typedef unsigned char uc __attribute ((may_alias)); typedef signed char sc __attribute ((may_alias)); typedef short int s __attribute ((may_alias)); typedef unsigned int u __attribute ((may_alias)); typedef long int l __attribute ((may_alias)); typedef long long int ll __attribute ((may_alias)); typedef wchar_t w __attribute ((may_alias)); typedef bool b __attribute ((may_alias)); void foo1 (unsigned char, signed char, short int, unsigned int, long int, bool) { } void foo1 (uc, sc, s, u, l, b) { } which isn't rejected (as C++ treats them as overloads), but are mangled the same, so this fails to assemble. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|ICE with double and |[4.1/4.2/4.3 regression] ICE |attribute may_alias |with double and attribute | |may_alias Target Milestone|--- |4.1.3 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34936