This structures field and union type member comparison in a way to make obvious which comparisons are for field-decls and which are for the rest.
LTO Profile-bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-05-30 Richard Guenther <rguent...@suse.de> * gimple.c (gimple_types_compatible_p_1): Compare record and union type members properly. Index: gcc/gimple.c =================================================================== --- gcc/gimple.c (revision 174434) +++ gcc/gimple.c (working copy) @@ -3772,10 +3772,16 @@ gimple_types_compatible_p_1 (tree t1, tr f1 && f2; f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) { - /* The fields must have the same name, offset and type. */ + /* Different field kinds are not compatible. */ + if (TREE_CODE (f1) != TREE_CODE (f2)) + goto different_types; + /* Field decls must have the same name and offset. */ + if (TREE_CODE (f1) == FIELD_DECL + && (DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) + || !gimple_compare_field_offset (f1, f2))) + goto different_types; + /* All entities should have the same name and type. */ if (DECL_NAME (f1) != DECL_NAME (f2) - || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) - || !gimple_compare_field_offset (f1, f2) || !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), state, sccstack, sccstate, sccstate_obstack)) goto different_types;