Hi, this is patch I ended up testing. It ensures that canonical types of copies I create are same as of originals C++ FE has its own refernece type construction (cp_build_reference_type) and it creates additional pointer types with TYPE_REF_IS_RVALUE set and it has different TYPE_CANONICAL.
Obviously we do not see this in middle-end and we end up merging the types despite fact they have different TYPE_CANONICAL. I guess I can immitate the behaviour in fld_incomplete_type_of by implementing my own variant of build_pointer_type that also matches TYPE_CANONICAL of the pointer it creates. I wonder if there are better solutions? Honza Index: tree.c =================================================================== --- tree.c (revision 265807) +++ tree.c (working copy) @@ -5118,6 +5118,7 @@ fld_type_variant (tree first, tree t, st TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t); TYPE_NAME (v) = TYPE_NAME (t); TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t); + TYPE_CANONICAL (v) = TYPE_CANONICAL (t); add_tree_to_fld_list (v, fld); return v; } @@ -5146,6 +5147,10 @@ fld_incomplete_type_of (tree t, struct f else first = build_reference_type_for_mode (t2, TYPE_MODE (t), TYPE_REF_CAN_ALIAS_ALL (t)); + gcc_assert (TYPE_CANONICAL (t2) != t2 + && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)) + && TYPE_CANONICAL (first) + == TYPE_CANONICAL (TYPE_MAIN_VARIANT (t))); add_tree_to_fld_list (first, fld); return fld_type_variant (first, t, fld); } @@ -5169,6 +5174,7 @@ fld_incomplete_type_of (tree t, struct f SET_TYPE_MODE (copy, VOIDmode); SET_TYPE_ALIGN (copy, BITS_PER_UNIT); TYPE_SIZE_UNIT (copy) = NULL; + TYPE_CANONICAL (copy) = TYPE_CANONICAL (t); if (AGGREGATE_TYPE_P (t)) { TYPE_FIELDS (copy) = NULL;