------- 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

Reply via email to