This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/31564] Error: Type/rank mismatch in argument
- From: "pault at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 18 Aug 2007 06:04:31 -0000
- Subject: [Bug fortran/31564] Error: Type/rank mismatch in argument
- References: <bug-31564-14284@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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