Hi, this patch completes checking of type_non_common. THere is nothing too interesting except for the FIXME about Fortran. gfc_nonrestricted_types does deep type copying producing a type variant for arrays and structures, but it builds distinct type variant for pointers. This leads to fact that we can have a structure whose fields are not variants of the main variant. I think we could fix it in a same way as objective C does similar copying in objc_get_protocol_qualified_node which simply calls build_type_variant on the pointer and then rewrites TREE_TYPE of the pointer instead of going through build_pointer_type...
Bootstrapped/regtested x86_64-linux and ppc64-linux, will commit it shortly. Honza * tree.c (verify_type_variant): Check TYPE_VALUES_RAW and TYPE_PRECISION Index: tree.c =================================================================== --- tree.c (revision 222984) +++ tree.c (working copy) @@ -12577,6 +12577,98 @@ verify_type_variant (const_tree t, tree debug_tree (TYPE_BINFO (t)); return false; } + + /* Check various uses of TYPE_VALUES_RAW. */ + if (TREE_CODE (t) == ENUMERAL_TYPE + && TYPE_VALUES (t) != TYPE_VALUES (tv)) + { + error ("type variant has different TYPE_VALUES"); + debug_tree (tv); + error ("type variant's TYPE_VALUES"); + debug_tree (TYPE_VALUES (tv)); + error ("type's TYPE_VALUES"); + debug_tree (TYPE_VALUES (t)); + return false; + } + else if (TREE_CODE (t) == ARRAY_TYPE + && TYPE_DOMAIN (t) != TYPE_DOMAIN (tv)) + { + error ("type variant has different TYPE_DOMAIN"); + debug_tree (tv); + error ("type variant's TYPE_DOMAIN"); + debug_tree (TYPE_DOMAIN (tv)); + error ("type's TYPE_DOMAIN"); + debug_tree (TYPE_DOMAIN (t)); + return false; + } + /* Permit incomplete variants of complete type. While FEs may complete + all variants, this does not happen for C++ templates in all cases. */ + else if (RECORD_OR_UNION_TYPE_P (t) + && COMPLETE_TYPE_P (t) + && TYPE_FIELDS (t) != TYPE_FIELDS (tv)) + { + tree f1, f2; + + /* Fortran builds qualified variants as new records with items of + qualified type. Verify that they looks same. */ + for (f1 = TYPE_FIELDS (t), f2 = TYPE_FIELDS (tv); + f1 && f2; + f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) + if (TREE_CODE (f1) != FIELD_DECL || TREE_CODE (f2) != FIELD_DECL + || (TYPE_MAIN_VARIANT (TREE_TYPE (f1)) + != TYPE_MAIN_VARIANT (TREE_TYPE (f2)) + /* FIXME: gfc_nonrestricted_type builds all types as variants + with exception of pointer types. It deeply copies the type + which means that we may end up with a variant type + referring non-variant pointer. We may change it to + produce types as variants, too, like + objc_get_protocol_qualified_type does. */ + && !POINTER_TYPE_P (TREE_TYPE (f1))) + || DECL_FIELD_OFFSET (f1) != DECL_FIELD_OFFSET (f2) + || DECL_FIELD_BIT_OFFSET (f1) != DECL_FIELD_BIT_OFFSET (f2)) + break; + if (f1 || f2) + { + error ("type variant has different TYPE_FIELDS"); + debug_tree (tv); + error ("first mismatch is field"); + debug_tree (f1); + error ("and field"); + debug_tree (f2); + return false; + } + } + else if ((TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE) + && TYPE_ARG_TYPES (t) != TYPE_ARG_TYPES (tv)) + { + error ("type variant has different TYPE_ARG_TYPES"); + debug_tree (tv); + return false; + } + /* For C++ the qualified variant of array type is really an array type + of qualified TREE_TYPE. + objc builds variants of pointer where pointer to type is a variant, too + in objc_get_protocol_qualified_type. */ + if (TREE_TYPE (t) != TREE_TYPE (tv) + && ((TREE_CODE (t) != ARRAY_TYPE + && !POINTER_TYPE_P (t)) + || TYPE_MAIN_VARIANT (TREE_TYPE (t)) + != TYPE_MAIN_VARIANT (TREE_TYPE (tv)))) + { + error ("type variant has different TREE_TYPE"); + debug_tree (tv); + error ("type variant's TREE_TYPE"); + debug_tree (TREE_TYPE (tv)); + error ("type's TREE_TYPE"); + debug_tree (TREE_TYPE (t)); + return false; + } + if (TYPE_PRECISION (t) != TYPE_PRECISION (tv)) + { + error ("type variant has different TYPE_PRECISION"); + debug_tree (tv); + return false; + } return true; }