Hi Mikael, dear all,

On 07/05/2012 03:51 PM, Mikael Morin wrote:
I think the assumed-rank => rank == -1 convention should be documented in gfortran.h, at least for the gfc_array_spec::rank field.

Okay. (Done in my version, which is not yet attached.)

@@ -2990,6 +3008,15 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, + /* TS 29113, C407b. */
+      if (a->expr && a->expr->expr_type == EXPR_VARIABLE
+          && symbol_rank (a->expr->symtree->n.sym) == -1)
+ gfc_error ("Assumed-rank argument requires an explicit interface "
+             "at %L", &a->expr->where);
Doesn't this duplicates the other explicit interface diagnostic below...


@@ -2194,6 +2206,15 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
+        /* TS 29113, 6.2.  */
+        else if (arg->sym && arg->sym->as
+             && arg->sym->as->type == AS_ASSUMED_RANK)
+        gfc_error ("Procedure '%s' at %L with assumed-rank dummy "
+               "argument '%s' must have an explicit interface",
+               sym->name, &sym->declared_at, arg->sym->name);


No, they are different. Example:

! resolve_global_procedure:
! From the global symbol information, one knows in "foo"
! that the dummy argument of "bar" is an assumed-rank array
!
! (the actual argument has no assumed rank)
!
! This check is weak as it only works if both procedures
! are in the same translation unit.
!----------------------
subroutine foo
  integer :: x
  call bar(x) ! <<< ERROR HERE
end subroutine foo

subroutine bar(y)
  integer :: y(..)
end subroutine bar

! gfc_procedure_use:
! The actual argument is assumed rank. Then the dummy argument
! has to be assumed-rank, which requires that the interface must
! be explicit.
!
! Hence, that's a constraint check which has and can be diagnosed
! at compile time. (C407b)
!---------------------
subroutine foobar(z)
  integer :: z(..)
  call sub(z) ! << ERROR here
end subroutine foobar
!---------------------


@@ -5067,13 +5097,26 @@ resolve_variable (gfc_expr *e)
   /* TS 29113, 407b.  */
-  if (e->ts.type == BT_ASSUMED && !assumed_type_expr_allowed)
+  if (e->ts.type == BT_ASSUMED && !assumed_rank_type_expr_allowed)
     {
gfc_error ("Invalid expression with assumed-type variable %s at %L",
          sym->name, &e->where);
       return FAILURE;
     }

I'm not sure I understand the logic with the mixed assumed rank/type flag. According to C407c, shouldn't we check that e is assumed rank/shape?

No, that check is not for assumed-rank arrays but for (e.g. scalar) assumed type, TYPE(*). The check handles cases like:

  type(*) :: x
  print *, ubound(array, dim=x)

where "x" is not allowed, contrary to, e.g.,

  type(*) :: x(:)
  print *, ubound(x)

Thus, one needs to keep track whether "x" is allowed or is not allowed in an expression. As that's the same for assumed type and for assumed rank, I am using the same tracking variable, called assumed_rank_type_expr_allowed. A better name would be: assumed_rank_or_assumed_type_expr_allowed (or s/or/and/), however, I found my version clear enough and while it is already long, that variant would be even longer.


+  /* TS 29113, C535b.  */
+  if (((sym->ts.type == BT_CLASS && sym->attr.class_ok
+    && CLASS_DATA (sym)->as
+    && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
+       || (sym->ts.type != BT_CLASS && sym->as
+       && sym->as->type == AS_ASSUMED_RANK))
+      && !assumed_rank_type_expr_allowed)
+    {
+ gfc_error ("Invalid expression with assumed-rank variable %s at %L",
+         sym->name, &e->where);

The error message could be made more helpful. ;-)

Suggestions welcome. Example use would be:

x = x +1
call foo(x+1)
call sin(x)  ! Though that probably triggers elsewhere

I don't think the wording is that bad.

@@ -5084,6 +5127,22 @@ resolve_variable (gfc_expr *e)
       return FAILURE;
     }

+  /* TS 29113, C535b.  */
+  if (((sym->ts.type == BT_CLASS && sym->attr.class_ok
+    && CLASS_DATA (sym)->as
+    && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
+       || (sym->ts.type != BT_CLASS && sym->as
+       && sym->as->type == AS_ASSUMED_RANK))
+      && e->ref
+      && !(e->ref->type == REF_ARRAY && e->ref->u.ar.type == AR_FULL
+           && e->ref->next == NULL))
+    {
+      gfc_error ("Assumed-rank variable %s with designator at %L",
+                 sym->name, &e->ref->u.ar.where);

Ditto here. And I think that C535b is more about the context of the expression rather than the expression itself.

Here, I am lost. The check is that
  ubound(x(:))
  call bar (x(1))
  call bar2(x([1,3,5])
  call bar3(x(1:5:2))
or similar does not occur if "x" is assumed rank. That "(:)" is an (array) designator. Do you have a better suggestion? I could add the word "array" before "designator", but I would like to avoid to list all possible combinations.

From TS29113:
"C407b An assumed-type variable name shall not appear in a designator or ..."

From Fortran 2008:

"1.3.59 designator
name followed by zero or more component selectors, complex part selectors, array section selectors, array element selectors, image selectors, and substring selectors (6.1)"

[I think due to the arrayness, the '(:)' has to be inserted if one wants to use component, complex part, or substring selectors, thus they should be properly covered.]



Unless you have better wordings, I will later send a slightly updated patch with some minor changes and the scalarizer part ripped off.

Tobias

Reply via email to