diff options
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fortran/trans-types.c | 34 |
2 files changed, 31 insertions, 12 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 94e2418acf6..86aeeae89ec 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,14 @@ 2005-10-12 Paul Thomas <pault@gcc.gnu.org> + PR fortran/24092 + * trans-types.c (gfc_get_derived_type): Insert code to obtain backend + declaration for derived types, building if necessary. Return the + derived type if the fields have been built by this process. Otherwise, + continue as before but using the already obtained backend_decls for the + derived type components. Change the gcc_assert to act on the field. + +2005-10-12 Paul Thomas <pault@gcc.gnu.org> + PR fortran/18082 * decl.c (variable_decl): Make a new copy of the character length for each variable, when the expression is not a diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index e16db8836a9..81a90f1d373 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1415,21 +1415,30 @@ gfc_get_derived_type (gfc_symbol * derived) derived->backend_decl = typenode; } + /* Go through the derived type components, building them as + necessary. The reason for doing this now is that it is + possible to recurse back to this derived type through a + pointer component (PR24092). If this happens, the fields + will be built and so we can return the type. */ + for (c = derived->components; c; c = c->next) + { + if (c->ts.type != BT_DERIVED) + continue; + + if (!c->pointer || c->ts.derived->backend_decl == NULL) + c->ts.derived->backend_decl = gfc_get_derived_type (c->ts.derived); + } + + if (TYPE_FIELDS (derived->backend_decl)) + return derived->backend_decl; + /* Build the type member list. Install the newly created RECORD_TYPE node as DECL_CONTEXT of each FIELD_DECL. */ fieldlist = NULL_TREE; for (c = derived->components; c; c = c->next) { - if (c->ts.type == BT_DERIVED && c->pointer) - { - if (c->ts.derived->backend_decl) - /* We already saw this derived type so use the exiting type. - It doesn't matter if it is incomplete. */ - field_type = c->ts.derived->backend_decl; - else - /* Recurse into the type. */ - field_type = gfc_get_derived_type (c->ts.derived); - } + if (c->ts.type == BT_DERIVED) + field_type = c->ts.derived->backend_decl; else { if (c->ts.type == BT_CHARACTER) @@ -1464,8 +1473,9 @@ gfc_get_derived_type (gfc_symbol * derived) DECL_PACKED (field) |= TYPE_PACKED (typenode); - gcc_assert (!c->backend_decl); - c->backend_decl = field; + gcc_assert (field); + if (!c->backend_decl) + c->backend_decl = field; } /* Now we have the final fieldlist. Record it, then lay out the |