[Patch, Fortran] PR 47569 - fix ICE (regression) and fix diagnostic
Mikael Morin
mikael.morin@sfr.fr
Sat Feb 12 20:54:00 GMT 2011
On Saturday 12 February 2011 00:26:57 Tobias Burnus wrote:
> PR 47569 is about a 4.3/4.4/4.5/4.6 regression where
> "component%substring(1:2)" gave an ICE. Looking closer at the issue, I
> saw that the checks were a bit incomplete and inconsistent. I hope that
> with the patch the diagnostic is now correct.
>
> From the standards:
>
> F97: "If the actual argument is scalar, the corresponding dummy argument
> shall be scalar unless the actual argument is an element of an array
> that is not an assumed-shape or pointer array, or a substring of such an
> element."
>
> F2003: "If the actual argument is scalar, the corresponding dummy
> argument shall be scalar unless the actual argument is of type default
> character, of type character with the C character kind (15.1), or is an
> element or substring of an element of an array that is not an
> assumed-shape or pointer array."
>
> F2008 quote ("12.5.2.4 Ordinary dummy variables"):
> "If the actual argument is a noncoindexed scalar, the corresponding dummy
> argument shall be scalar unless the actual argument is default character,
> of type character with the C character kind (15.2.2),
If I understand this correctly, anything of default character kind type is
allowed. Thus...
> or is an element or
> substring of an element of an array that is not an assumed-shape,
> pointer, or
> polymorphic array."
>
>
>
> diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
> index 1e5df61..b555c3d 100644
> --- a/gcc/fortran/interface.c
> +++ b/gcc/fortran/interface.c
> @@ -1461,7 +1461,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr
*actual,
> int ranks_must_agree, int is_elemental, locus *where)
> {
> gfc_ref *ref;
> - bool rank_check;
> + bool rank_check, is_pointer;
>
> /* If the formal arg has type BT_VOID, it's to one of the iso_c_binding
> procs c_f_pointer or c_f_procpointer, and we need to accept most
> @@ -1672,23 +1672,58 @@ compare_parameter (gfc_symbol *formal, gfc_expr
*actual,
> return 1;
>
> /* At this point, we are considering a scalar passed to an array. This
> - is valid (cf. F95 12.4.1.1; F2003 12.4.1.2),
> + is valid (cf. F95 12.4.1.1, F2003 12.4.1.2, and F2008 12.5.2.4),
> - if the actual argument is (a substring of) an element of a
> - non-assumed-shape/non-pointer array;
> - - (F2003) if the actual argument is of type character. */
> + non-assumed-shape/non-pointer/non-polymorphic array;
> + - (F2003) if the actual argument is of type character of
default/c_char
> + kind. */
... one could/should return early here for default (or C_CHAR) kind characters
?
That would mean some lines previously marked as "! Valid F2003" in the
testsuite could/should remain so.
> +
> + is_pointer = actual->expr_type == EXPR_VARIABLE
> + ? actual->symtree->n.sym->attr.pointer : false;
>
> for (ref = actual->ref; ref; ref = ref->next)
> - if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT
> - && ref->u.ar.dimen > 0)
> - break;
> + {
> + if (ref->type == REF_COMPONENT)
> + is_pointer = ref->u.c.component->attr.pointer;
> + else if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT
> + && ref->u.ar.dimen > 0
> + && (!ref->next
> + || (ref->next->type == REF_SUBSTRING && !ref->next-
>next)))
> + break;
> + }
> +
> + if (actual->expr_type != EXPR_NULL
> + && (is_pointer || (ref && ref->u.ar.as->type == AS_ASSUMED_SHAPE)))
> + {
> + if (where)
> + gfc_error ("Scalar pointer or element of assumed-shaped or pointer "
> + "array passed to array dummy argument '%s' at %L",
> + formal->name, &actual->where);
> + return 0;
> + }
> +
> + if (actual->ts.type == BT_CLASS && actual->expr_type != EXPR_NULL)
> + {
> + if (where)
> + gfc_error ("Polymorphic scalar passed to array dummy argument '%s' "
> + "at %L", formal->name, &actual->where);
> + return 0;
> + }
>
> - /* Not an array element. */
> - if (formal->ts.type == BT_CHARACTER
> - && (ref == NULL
> - || (actual->expr_type == EXPR_VARIABLE
> - && (actual->symtree->n.sym->as->type == AS_ASSUMED_SHAPE
> - || actual->symtree->n.sym->attr.pointer))))
> + if (formal->ts.type == BT_CHARACTER && actual->expr_type != EXPR_NULL &&
!ref)
> {
> + if (formal->ts.kind == 4 && where
> + && (gfc_option.allow_std & GFC_STD_GNU) == 0)
> + {
> + gfc_error ("Extension: Scalar ISO-10646 CHARACTER actual argument
"
> + "with array dummy argument '%s' at %L",
> + formal->name, &actual->where);
> + return 0;
> + }
> +
> + if (formal->ts.kind == 4 && (gfc_option.allow_std & GFC_STD_GNU) ==
0)
> + return 0;
- I find it clearer to have the conditions merged and the error under a "if
(where)" like you did elsewhere.
- Is there a reason not to use gfc_notify_std ?
- Also, I think the error message above could be interpreted as if the problem
is the presence of non-ascii characters in the actual argument. So I would
preferably stick to the standard wording (non either default or C kind
character actual argument) even if it doesn't sound great.
- Last but not least, shouldn't actual->ts.kind be tested instead of formal-
>ts.kind ?
> +
> if (where && (gfc_option.allow_std & GFC_STD_F2003) == 0)
> {
> gfc_error ("Fortran 2003: Scalar CHARACTER actual argument with "
> @@ -1709,17 +1744,6 @@ compare_parameter (gfc_symbol *formal, gfc_expr
*actual,
> return 0;
> }
>
> - if (actual->expr_type == EXPR_VARIABLE
> - && actual->symtree->n.sym->as
> - && (actual->symtree->n.sym->as->type == AS_ASSUMED_SHAPE
> - || actual->symtree->n.sym->attr.pointer))
> - {
> - if (where)
> - gfc_error ("Element of assumed-shaped array passed to dummy "
> - "argument '%s' at %L", formal->name, &actual->where);
> - return 0;
> - }
> -
> return 1;
> }
>
The rest (pointer, class and assumed shape) seem properly handled.
Mikael
More information about the Fortran
mailing list