Hi all,

(I guess someone should either pick it up - or file a problem report
with the testcase and and link to this email.)

Short version: I think there is a bug in not properly resolving 'iren(:)',
which can initially be both an assumed-shape or deferred-shape array and
it might be only know at the end of the specification part whether it is
one or the other (e.g. whether a 'pointer :: iren' or 'allocatable :: iren'
follows or not).

The problem is that for the overriding function, the type comparison happens
before it is resolved; but the question is why?

* * *

Long version:

[email protected] wrote:

   30 |     procedure, pass (a) :: csgrw    => psb_d_mf_csgrw
      |             1
Error: Argument mismatch for the overriding procedure ‘csgrw’ at (1): Shape mismatch in argument 'iren'

If I look at the file in the debugger, I see:

(gdb) p s1->ns->proc_name->name
$12 = 0x7ffff7215710 "psb_d_mf_csgrw"
(gdb) p s1->as->type
$13 = AS_DEFERRED

(gdb) p s2->ns->proc_name->name
$14 = 0x7ffff7226000 "psb_r_base_csgrw"
(gdb) p s2->as->type
$15 = AS_ASSUMED_SHAPE

There is of course the parsing problem that 'iren(:)'.
Assume:
  subroutine sub(iren)
    integer :: iren(:)
this can be either; for instance, if there is a following
  allocatable :: iren
it becomes an deferred array - but if there is no
pointer/allocatable attribute until the end of the
declaration part, it is an assumed-shape array.

* * *

Thus, this needs to be eventually resolved, but seemingly
is only in one case but not in the other.

In gfc_check_dummy_characteristics, there is the following code:

      /* Sometimes the ambiguity between deferred shape and assumed shape
         does not get resolved in module procedures, where the only explicit
         declaration of the dummy is in the interface.  */
      if (s1->ns->proc_name && s1->ns->proc_name->attr.module_procedure
          && s1->as->type == AS_ASSUMED_SHAPE
          && s2->as->type == AS_DEFERRED)
        ...
        s2->as->type = AS_ASSUMED_SHAPE

[The latter is a bit odd: While there is a prior check for s1 vs. s2
for being both pointer or both allocatable, bluntly setting it to
assumed-shape feels wrong.]

Here, s1 == "iren" and s1->ns->proc_name == "psb_d_mf_csgrw", but the
latter is not a module procedure, but just attr.external and attr.subroutine,
even though it comes from a module (s1->ns->parent->proc_name->attr.flavor == 
FL_MODULE).

It seems as if we need to properly resolve it in either case to 
AS_ASSUMED_SHAPE.

This seems to be handled in gfc_resolve_formal_arglist, but presumably not being
called in this case.

The code path seems to be:

gfc_resolve → resolve_types → resolve_contained_functions
→ resolve_formal_arglists → gfc_traverse_ns (ns, find_arglists);

With:

find_arglists (gfc_symbol *sym)
{
  if (sym->attr.if_source == IFSRC_UNKNOWN || sym->ns != gfc_current_ns
      || gfc_fl_struct (sym->attr.flavor) || sym->attr.intrinsic)
    return;

  gfc_resolve_formal_arglist (sym);
}

And in the function called there does:

      if (as && as->rank > 0 && as->type == AS_DEFERRED
          && ((sym->ts.type != BT_CLASS
               && !(sym->attr.pointer || sym->attr.allocatable))
...
          as->type = AS_ASSUMED_SHAPE;

This code is executed for the base function – but it is not called
before the error message is shown.

* * *

In principle, there is:

resolve_types
{
  ...
  resolve_contained_functions (ns);
  ...
  gfc_traverse_ns (ns, resolve_symbol);

but for some reasons, this does not trigger for in this case as the
call tree for the failing case is:

resolve_types → resolve_symbol → resolve_fl_derived
→ resolve_typebound_procedures → resolve_typebound_procedure
→ gfc_check_typebound_override

which fails as shown above.

The .mod file contains the proper ASSUMED_SHAPE and also the
debugger shows that the issue is in the overridden function.

The question is why does the find_arglists does not find and
handle it before resolve_symbol and then later
gfc_check_typebound_override is called?


Tobias

Reply via email to