> Hi, > in fld_type_variant I lost code copying alignment. This patch fixes it > and also checks that newly constructed variant is indeed compatible. > > Bootstrapped/regtested x86_64-linux, comitted as obvious. Hi, it turns out that situation is more subtle. We need to copy aliases for normal types (such as variants of pointers) but we need to not copy them when we create incomplete variant of complete type. Incomplete variant alignment is always BITS_PER_UNIT.
I have regtested & lto-bootstrapped the attached patch which furhter reduces number of type duplicates from 500 to 200. Honza * tree.c (fld_type_variant_equal_p): Skip TYPE_ALIGN check when building incomplete variant of complete type. (fld_type_variant): Do not copy TYPE_ALIGN when building incomplete variant of complete type. Index: tree.c =================================================================== --- tree.c (revision 265848) +++ tree.c (working copy) @@ -5106,12 +5106,15 @@ static bool fld_type_variant_equal_p (tree t, tree v) { if (TYPE_QUALS (t) != TYPE_QUALS (v) - || TYPE_ALIGN (t) != TYPE_ALIGN (v) + /* We want to match incomplete variants with complete types. + In this case we need to ignore alignment. */ + || ((!RECORD_OR_UNION_TYPE_P (t) || COMPLETE_TYPE_P (v)) + && TYPE_ALIGN (t) != TYPE_ALIGN (v)) || fld_simplified_type_name (t) != fld_simplified_type_name (v) || !attribute_list_equal (TYPE_ATTRIBUTES (t), TYPE_ATTRIBUTES (v))) return false; return true; } @@ -5134,7 +5137,10 @@ fld_type_variant (tree first, tree t, st TYPE_NAME (v) = TYPE_NAME (t); TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t); TYPE_CANONICAL (v) = TYPE_CANONICAL (t); - SET_TYPE_ALIGN (v, TYPE_ALIGN (t)); + /* Variants of incomplete types should have alignment + set to BITS_PER_UNIT. Do not copy the actual alignment. */ + if (!RECORD_OR_UNION_TYPE_P (v) || COMPLETE_TYPE_P (v)) + SET_TYPE_ALIGN (v, TYPE_ALIGN (t)); gcc_checking_assert (fld_type_variant_equal_p (t,v)); add_tree_to_fld_list (v, fld); return v;