http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45586
--- Comment #38 from Mikael Morin <mikael at gcc dot gnu.org> 2011-01-25 14:32:28 UTC --- The patch looks good. Somewhat hackish as you acknowledge, but worth submitting anyway. A few minor comments below. > Index: fortran/trans-expr.c > =================================================================== > --- fortran/trans-expr.c (revision 168749) > +++ fortran/trans-expr.c (working copy) > @@ -504,6 +504,19 @@ gfc_conv_component_ref (gfc_se * se, gfc > field = c->backend_decl; > gcc_assert (TREE_CODE (field) == FIELD_DECL); > decl = se->expr; > + if (DECL_CONTEXT (field) != TREE_TYPE (decl)) > + { > + tree f2 = c->backend_decl2; > + if (f2 && DECL_FIELD_CONTEXT (f2) == TREE_TYPE (decl)) > + ; > + else for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN > (f2)) I prefer `if (!cond) ...' instead of `if (cond) ; else ...' > Index: fortran/gfortran.h > =================================================================== > --- fortran/gfortran.h (revision 168749) > +++ fortran/gfortran.h (working copy) > @@ -934,6 +934,7 @@ typedef struct gfc_component > gfc_array_spec *as; > > tree backend_decl; > + tree backend_decl2; More descriptive name (e.g. restrict_backend_decl or target_backend_decl or ...) and comment explaining the need for it appreciated. One could have the combinatorial explosion of backend_decls here as said Michael. In any case it can be safely removed if needed, as it is just a cache. > locus loc; > struct gfc_expr *initializer; > struct gfc_component *next; > Index: fortran/trans-types.c > =================================================================== > --- fortran/trans-types.c (revision 168749) > +++ fortran/trans-types.c (working copy) > @@ -1746,6 +1746,80 @@ gfc_build_pointer_type (gfc_symbol * sym > else > return build_pointer_type (type); > } > + > +static tree > +gfc_nonrestricted_type (tree t) > +{ > + tree ret = t; > + if (!TYPE_LANG_SPECIFIC (t)) > + TYPE_LANG_SPECIFIC (t) > + = ggc_alloc_cleared_lang_type (sizeof (struct lang_type)); > + if (TYPE_LANG_SPECIFIC (t)->nonrestricted_type) > + return TYPE_LANG_SPECIFIC (t)->nonrestricted_type; > + switch (TREE_CODE (t)) > + { > + default: > + break; > + > + case POINTER_TYPE: > + case REFERENCE_TYPE: > + ret = build_qualified_type (t, TYPE_QUALS (t) & ~TYPE_QUAL_RESTRICT); Isn't it necessary to call gfc_nonrestricted_type on TREE_TYPE (t) here ? > + break; > + > + case ARRAY_TYPE: > + { > + tree elemtype = gfc_nonrestricted_type (TREE_TYPE (t)); > + if (elemtype == TREE_TYPE (t)) > + ret = t; > + else > + { > + ret = copy_node (t); > + TREE_TYPE (t) = elemtype; > + /* ??? Change some TYPE_LANG_SPECIFICs too? */ > + } > + } > + break; > + > + case RECORD_TYPE: > + case UNION_TYPE: > + case QUAL_UNION_TYPE: > + { > + tree field, *chain; > + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) > + if (TREE_CODE (field) == FIELD_DECL) > + { > + tree elemtype = gfc_nonrestricted_type (TREE_TYPE (field)); > + if (elemtype != TREE_TYPE (field)) > + break; > + } > + if (!field) > + break; > + ret = copy_node (t); > + TYPE_FIELDS (ret) = NULL_TREE; > + chain = &TYPE_FIELDS (ret); > + for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) > + { > + tree newfield = copy_node (field); > + DECL_CONTEXT (newfield) = ret; > + DECL_CHAIN (newfield) = NULL_TREE; > + if (TYPE_FIELDS (ret) == NULL_TREE) > + TYPE_FIELDS (ret) = newfield; Those two lines seem to duplicate the line below (as initially chain points to &TYPE_FIELDS(ret)). > + *chain = newfield; > + chain = &DECL_CHAIN (newfield); > + > + if (TREE_CODE (field) == FIELD_DECL) > + { > + tree elemtype = gfc_nonrestricted_type (TREE_TYPE (field)); > + TREE_TYPE (newfield) = elemtype; > + } > + } > + } > + break; > + } > + TYPE_LANG_SPECIFIC (t)->nonrestricted_type = ret; Don't know if it is absolutely necessary, but one might add also : TYPE_LANG_SPECIFIC (ret)->nonrestricted_type = ret; > + return ret; > +} > + > > /* Return the type for a symbol. Special handling is required for character > types to get the correct level of indirection. > @@ -1789,6 +1863,9 @@ gfc_sym_type (gfc_symbol * sym) > else > type = gfc_typenode_for_spec (&sym->ts); > > + if (sym->attr.pointer) > + type = gfc_nonrestricted_type (type); > + This is missing the target attribute, so you may preferably use the restricted boolean a few lines below. > if (sym->attr.dummy && !sym->attr.function && !sym->attr.value) > byref = 1; > else > Index: fortran/trans.h > =================================================================== > --- fortran/trans.h (revision 168749) > +++ fortran/trans.h (working copy) > @@ -700,6 +700,7 @@ struct GTY((variable_size)) lang_type { > tree dataptr_type; > tree span; > tree base_decl[2]; > + tree nonrestricted_type; > }; > > struct GTY((variable_size)) lang_decl {