When I compile the module listed below I get the message: c3.f90:15.23: USE cdf_aux_mod 1 Error: Type/rank mismatch in argument 'arg_name' at (1) g95 and Lahey do not produce error messages. Is it legal? MODULE cdf_aux_mod TYPE :: the_distribution INTEGER :: parameters(1) END TYPE the_distribution TYPE (the_distribution), PARAMETER :: the_beta = the_distribution((/0/)) CONTAINS SUBROUTINE set_bound(arg_name) INTEGER, INTENT (IN) :: arg_name END SUBROUTINE set_bound END MODULE cdf_aux_mod MODULE cdf_beta_mod CONTAINS SUBROUTINE cdf_beta() USE cdf_aux_mod INTEGER :: which CALL set_bound(the_beta%parameters(which)) END SUBROUTINE cdf_beta END MODULE cdf_beta_mod
The code is illegal, but in accordance with the error message. You need to set WHICH to 1 via either INTEGER :: which = 1 or which = 1 This however doesn't fix the problem. If you change the call to CALL set_bound(the_beta%parameters(1)) then it compiles. So, it looks as if gfortran isn't properly evaluating the derived type arguments.
Created attachment 13618 [details] decl.c patch (not check-gfortran tested) Erik, are you still working on this? One should also check that: CALL set_bound(the_beta%parameters(1:which)) is rejected. (This does not seem to call compare_parameter). First step, to get it further is to modify compare_parameter (see attachment). However, this then crashes in trans-expr.c's gfc_conv_function_call (l.2148) [invalid memory access].
(In reply to comment #2) > Created an attachment (id=13618) [edit] > decl.c patch (not check-gfortran tested) > > Erik, are you still working on this? Officially, yes :-) I.e., I began, but now I haven't had time to look at it for a couple of weeks. Just go ahead and fix it if you are interested.
(In reply to comment #3) > (In reply to comment #2) > > Created an attachment (id=13618) [edit] > > decl.c patch (not check-gfortran tested) > > > > Erik, are you still working on this? > > Officially, yes :-) > I.e., I began, but now I haven't had time to look at it for a couple of weeks. > Just go ahead and fix it if you are interested. Just to add one more data point: It's not just procedure arguments that are problematic; it's expression like foo%array(variable) in general, where foo is a PARAMETER. E.g. this piece of code is also rejected: SUBROUTINE cdf_beta() TYPE :: the_distribution INTEGER :: parameters(1) END TYPE the_distribution TYPE (the_distribution), PARAMETER :: the_beta = the_distribution((/0/)) INTEGER :: which, pooh which = 1 pooh = the_beta%parameters(which) END SUBROUTINE cdf_beta erik:~/gcc$ gfortran pr31564.f90 pr31564.f90:12.8: pooh = the_beta%parameters(which) 1 Error: Incompatible ranks 0 and 1 in assignment at (1)
I never seem to get time to do anything about this bug, so I'll better unassign it from me.
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;
To my surprise, I have a fix for this one. I'll post it to the list in the next 48 hours. Paul
Subject: Bug 31564 Author: pault Date: Wed Sep 5 13:34:25 2007 New Revision: 128130 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128130 Log: 2007-09-05 Paul Thomas <pault@gcc.gnu.org> PR fortran/31564 * primary.c (gfc_match_rvalue): Make expressions that refer to derived type parameters that have array references into variable expressions. Remove references to use association from the symbol. PR fortran/33241 * decl.c (add_init_expr_to_sym): Provide assumed character length parameters with the length of the initialization expression, if a constant, or that of the first element of an array. 2007-09-05 Paul Thomas <pault@gcc.gnu.org> PR fortran/31564 * gfortran.dg/derived_comp_array_ref_2.f90: New test. PR fortran/33241 * gfortran.dg/char_length_10.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/char_length_10.f90 trunk/gcc/testsuite/gfortran.dg/derived_comp_array_ref_2.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/decl.c trunk/gcc/fortran/primary.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk. Paul
Subject: Bug number PR31564 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-09/msg00319.html