[Bug fortran/31564] Error: Type/rank mismatch in argument

pault at gcc dot gnu dot org gcc-bugzilla@gcc.gnu.org
Sat Aug 18 06:04:00 GMT 2007



------- Comment #6 from pault at gcc dot gnu dot org  2007-08-18 06:04 -------
This one is a real head-banger.  The array element reference is being
completely ignored in translation.  I tried simplifying it by grabbing out the
array component and attaching the array reference to it.  The resulting
expression looks fine but the reference is ignore further downstream; I have
run out of time to look at this, for a while.  Note that replacing the array
component of a derived type parameter with a parameter array works fine.

Just for the record, my attempt to fix this by simplification appears below.

Paul

Index: gcc/fortran/expr.c
===================================================================
*** gcc/fortran/expr.c  (revision 127505)
--- gcc/fortran/expr.c  (working copy)
*************** simplify_ref_chain (gfc_ref *ref, int ty
*** 1461,1466 ****
--- 1461,1535 ----
  }


+ /* Simplify structure references.  */
+
+ static void
+ simplify_structure_refs (gfc_expr *e)
+ {
+   int n;
+   bool seen_array_ref;
+   bool reduced_structure = false;
+   gfc_ref *ref;
+   gfc_component *cmp;
+   gfc_constructor *ctr;
+   gfc_expr *p = e;
+   gfc_symtree *st;
+
+   if (e->expr_type != EXPR_STRUCTURE)
+     return;
+
+ start:
+   seen_array_ref = false;
+   ref = p->ref;
+
+   for (; ref; ref = ref->next)
+     {
+       switch (ref->type)
+       {
+       case REF_COMPONENT:
+         if (p->symtree
+               && p->symtree->n.sym->ts.derived
+               && !p->ts.derived)
+           p->ts = p->symtree->n.sym->ts;
+
+         if (seen_array_ref || !p->ts.derived)
+           break;
+
+         ctr = p->value.constructor;
+         cmp = p->ts.derived->components;
+         for (;ctr; ctr = ctr->next, cmp = cmp->next)
+           {
+             if (ref->u.c.component != cmp || ctr->expr == NULL)
+               continue;
+             p = ctr->expr;
+             p->ts = cmp->ts;
+             ctr->expr = NULL;
+             p->ref = ref->next;
+             ref->next = NULL;
+             gfc_free_expr (e);
+             *e = *p;
+             reduced_structure = true;
+             goto start;
+           }
+         break;
+
+       case REF_ARRAY:
+         for (n = 0; n < ref->u.ar.dimen; n++)
+           {
+             if (reduced_structure
+                   && ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
+               p->rank--;
+           }
+         seen_array_ref = true;
+         break;
+
+       default:
+         break;
+       }
+     }
+ }
+
+
  /* Try to substitute the value of a parameter variable.  */

  static try
*************** gfc_simplify_expr (gfc_expr *p, int type
*** 1604,1609 ****
--- 1673,1681 ----
        if (simplify_ref_chain (p->ref, type) == FAILURE)
        return FAILURE;

+       if (p->ref)
+         simplify_structure_refs (p);
+
        if (simplify_constructor (p->value.constructor, type) == FAILURE)
        return FAILURE;

*************** gfc_check_pointer_assign (gfc_expr *lval
*** 2749,2755 ****

    is_pure = gfc_pure (NULL);

!   if (is_pure && gfc_impure_variable (lvalue->symtree->n.sym))
      {
        gfc_error ("Bad pointer object in PURE procedure at %L",
&lvalue->where)
;
        return FAILURE;
--- 2821,2828 ----

    is_pure = gfc_pure (NULL);

!   if (is_pure && gfc_impure_variable (lvalue->symtree->n.sym)
!       && lvalue->symtree->n.sym->value != rvalue)
      {
        gfc_error ("Bad pointer object in PURE procedure at %L",
&lvalue->where)
;
        return FAILURE;


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31564



More information about the Gcc-bugs mailing list