------- Comment #8 from tobi at gcc dot gnu dot org 2007-10-07 17:16 ------- Something like the patch below fails unfortunately -- when resolving arglists we still don't know enough about the callee (viz the checks of ptype, that are already a hack on top of my original patch attempt) to determine what is legal. It's probably possible to add another scan over the argument list once the procedure call has been resolved, but I haven't yet looked into this. Also, it doesn't really feel proper.
diff -r 8c9190af9173 gcc/fortran/resolve.c --- a/gcc/fortran/resolve.c Sun Oct 07 11:45:15 2007 +0000 +++ b/gcc/fortran/resolve.c Sun Oct 07 19:11:46 2007 +0200 @@ -940,6 +940,31 @@ resolve_assumed_size_actual (gfc_expr *e } +/* Given a derived type, returns true if the type is use-associated or + has the SEQUENCE or BIND(C) attributes and has no PRIVATE + componentes. In these cases it may be used as dummy arguments in + calls without explicit interface. */ + +static bool +interchangeable_type (gfc_typespec *ts) +{ + gfc_symbol *sym = ts->derived; + + gcc_assert (ts->type == BT_DERIVED); + + /* We don't have to recurse through potential derived type members, + because the type having either of use_assoc, is_bin_c or sequence + set requires this for the subtypes. This requirement is checked + elsewhere. Likewise, if the private_comp attribute is set in a + component, it is inherited by the type. */ + if (sym->ns != gfc_current_ns || sym->attr.use_assoc) + return true; + + return ((sym->attr.is_bind_c || sym->attr.sequence) + && !sym->attr.private_comp); +} + + /* Resolve an actual argument list. Most of the time, this is just resolving the expressions in the list. The exception is that we sometimes have to decide whether arguments @@ -975,6 +1000,7 @@ resolve_actual_arglist (gfc_actual_argli { if (gfc_resolve_expr (e) != SUCCESS) return FAILURE; + goto argument_list; } @@ -1114,6 +1140,15 @@ resolve_actual_arglist (gfc_actual_argli return FAILURE; argument_list: + if ((ptype == PROC_EXTERNAL || ptype == PROC_UNKNOWN) + && e->ts.type == BT_DERIVED + && !interchangeable_type (&e->ts)) + { + gfc_error ("Derived type '%s' cannot appear in argument list " + "at %L", e->ts.derived->name, &e->where); + return FAILURE; + } + /* Check argument list functions %VAL, %LOC and %REF. There is nothing to do for %REF. */ if (arg->name && arg->name[0] == '%') -- tobi at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |tobi at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22571