diff options
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 68 |
1 files changed, 58 insertions, 10 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 5ba4c8e..5f5ce56 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -4328,6 +4328,60 @@ resolve_values (gfc_symbol * sym) } +/* Resolve a charlen structure. */ + +static try +resolve_charlen (gfc_charlen *cl) +{ + if (cl->resolved) + return SUCCESS; + + cl->resolved = 1; + + if (gfc_resolve_expr (cl->length) == FAILURE) + return FAILURE; + + if (gfc_simplify_expr (cl->length, 0) == FAILURE) + return FAILURE; + + if (gfc_specification_expr (cl->length) == FAILURE) + return FAILURE; + + return SUCCESS; +} + + +/* Resolve the components of a derived type. */ + +static try +resolve_derived (gfc_symbol *sym) +{ + gfc_component *c; + + for (c = sym->components; c != NULL; c = c->next) + { + if (c->ts.type == BT_CHARACTER) + { + if (resolve_charlen (c->ts.cl) == FAILURE) + return FAILURE; + + if (c->ts.cl->length == NULL + || !gfc_is_constant_expr (c->ts.cl->length)) + { + gfc_error ("Character length of component '%s' needs to " + "be a constant specification expression at %L.", + c->name, + c->ts.cl->length ? &c->ts.cl->length->where : &c->loc); + return FAILURE; + } + } + + /* TODO: Anything else that should be done here? */ + } + + return SUCCESS; +} + /* Do anything necessary to resolve a symbol. Right now, we just assume that an otherwise unknown symbol is a variable. This sort of thing commonly happens for symbols in module. */ @@ -4380,6 +4434,9 @@ resolve_symbol (gfc_symbol * sym) } } + if (sym->attr.flavor == FL_DERIVED && resolve_derived (sym) == FAILURE) + return; + /* Symbols that are module procedures with results (functions) have the types and array specification copied for type checking in procedures that call them, as well as for saving to a module @@ -5588,16 +5645,7 @@ gfc_resolve (gfc_namespace * ns) gfc_check_interfaces (ns); for (cl = ns->cl_list; cl; cl = cl->next) - { - if (cl->length == NULL || gfc_resolve_expr (cl->length) == FAILURE) - continue; - - if (gfc_simplify_expr (cl->length, 0) == FAILURE) - continue; - - if (gfc_specification_expr (cl->length) == FAILURE) - continue; - } + resolve_charlen (cl); gfc_traverse_ns (ns, resolve_values); |