type-bound procedures, use association, and rogue namespaces

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

type-bound procedures, use association, and rogue namespaces

Steve Kargl
So, I've taken a look at PR 89647, and it seems that
the mechanism for resolving type-bound procedures does
not know about USE association.  In resolve.c,
resolve_typebound_procedure() at lines 13540 (or so)
we have a type-bound entity, but its symbol has not
been resolved.  I've added this bit of code (sorry
about whitespace)

if (!proc->resolved
    && proc->attr.function == 0 && proc->attr.subroutine == 0)
  {
     gfc_symbol *tmp;
     gfc_find_symbol (proc->name, gfc_current_ns->parent, 1, &tmp);
     proc = tmp;
   }

which actually finds the USE associated symbol.  With Ian's
code and setting a breakpoint in gdb

(gdb) b resolve.c:13545
Breakpoint 1 at 0x85c618: file ../../gccx/gcc/fortran/resolve.c, line 13545.
(gdb) run a.f90
Starting program: /safe/sgk/work/x/libexec/gcc/x86_64-unknown-freebsd13.0/10.0.0/f951 a.f90

Breakpoint 1, resolve_typebound_procedure (stree=0x2023feb10)
    at ../../gccx/gcc/fortran/resolve.c:13545
13545             proc = tmp;
(gdb) p stree->n.tb->u.specific->n.sym
$1 = (gfc_symbol *) 0x202eceb00
(gdb) p proc
$2 = (gfc_symbol *) 0x202eceb00
(gdb) p tmp
$3 = (gfc_symbol *) 0x202ecdf00
(gdb) call debug(proc)
|| symbol: 'true'        
  type spec : (UNKNOWN 0)
  attributes: (PROCEDURE )
(gdb) call debug(tmp)
|| symbol: 'true'        
  type spec : (LOGICAL 4)
  attributes: (PROCEDURE MODULE-PROC  USE-ASSOC(m1) FUNCTION IMPLICIT_PURE)
  result: b

Doing the assignment 'proc = tmp' get me pass the first hurdle.
Unfortnately, one needs to do something like

  stree->n.tb->u.specific->n.sym = tmp;

as well, but this leads to an ICE (possibly from freeing the symbol
twice).

I've tried the obvious modification of adding 'resolve_symbol (proc)'
as the first statement in the above block of code.  This, indeed,
resolves the symbol but it puts it in the namespace of the local
scope of the function.  It does not find the USE associated symbol
(i.e., tmp).  I also looked for a gfc_copy_sym (proc, tmp) function,
but came up empty.  So, how does one update a symbol and get it
recognized as USE associated?

--
Steve
Reply | Threaded
Open this post in threaded view
|

Re: type-bound procedures, use association, and rogue namespaces

Steve Kargl
On Thu, Jun 13, 2019 at 12:55:06PM -0700, Steve Kargl wrote:

> So, I've taken a look at PR 89647, and it seems that
> the mechanism for resolving type-bound procedures does
> not know about USE association.  In resolve.c,
> resolve_typebound_procedure() at lines 13540 (or so)
> we have a type-bound entity, but its symbol has not
> been resolved.  I've added this bit of code (sorry
> about whitespace)
>
> if (!proc->resolved
>     && proc->attr.function == 0 && proc->attr.subroutine == 0)
>   {
>      gfc_symbol *tmp;
>      gfc_find_symbol (proc->name, gfc_current_ns->parent, 1, &tmp);
>      proc = tmp;
>    }
>
> which actually finds the USE associated symbol.  With Ian's
> code and setting a breakpoint in gdb
>
> (gdb) b resolve.c:13545
> Breakpoint 1 at 0x85c618: file ../../gccx/gcc/fortran/resolve.c, line 13545.
> (gdb) run a.f90
> Starting program: /safe/sgk/work/x/libexec/gcc/x86_64-unknown-freebsd13.0/10.0.0/f951 a.f90
>
> Breakpoint 1, resolve_typebound_procedure (stree=0x2023feb10)
>     at ../../gccx/gcc/fortran/resolve.c:13545
> 13545             proc = tmp;
> (gdb) p stree->n.tb->u.specific->n.sym
> $1 = (gfc_symbol *) 0x202eceb00
> (gdb) p proc
> $2 = (gfc_symbol *) 0x202eceb00
> (gdb) p tmp
> $3 = (gfc_symbol *) 0x202ecdf00
> (gdb) call debug(proc)
> || symbol: 'true'        
>   type spec : (UNKNOWN 0)
>   attributes: (PROCEDURE )
> (gdb) call debug(tmp)
> || symbol: 'true'        
>   type spec : (LOGICAL 4)
>   attributes: (PROCEDURE MODULE-PROC  USE-ASSOC(m1) FUNCTION IMPLICIT_PURE)
>   result: b
>
> Doing the assignment 'proc = tmp' get me pass the first hurdle.
> Unfortnately, one needs to do something like
>
>   stree->n.tb->u.specific->n.sym = tmp;
>
> as well, but this leads to an ICE (possibly from freeing the symbol
> twice).
>
> I've tried the obvious modification of adding 'resolve_symbol (proc)'
> as the first statement in the above block of code.  This, indeed,
> resolves the symbol but it puts it in the namespace of the local
> scope of the function.  It does not find the USE associated symbol
> (i.e., tmp).  I also looked for a gfc_copy_sym (proc, tmp) function,
> but came up empty.  So, how does one update a symbol and get it
> recognized as USE associated?
>

Well, this feels like a kludge, but appears to work.  Anyone
who is familiar with type-bound procedures have a better
idea?

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c (revision 272259)
+++ gcc/fortran/resolve.c (working copy)
@@ -13536,14 +13537,34 @@ resolve_typebound_procedure (gfc_symtree* stree)
     }
   else
     {
+      /* If proc has not been resolved at this point, proc->name may
+ actually be a USE associated entity. See PR fortran/89647. */
+      if (!proc->resolved
+  && proc->attr.function == 0 && proc->attr.subroutine == 0)
+ {
+  gfc_symbol *tmp;
+  gfc_find_symbol (proc->name, gfc_current_ns->parent, 1, &tmp);
+  if (tmp->attr.use_assoc)
+    {
+      proc->module = tmp->module;
+      proc->attr.proc = tmp->attr.proc;
+      proc->attr.function = tmp->attr.function;
+      proc->attr.subroutine = tmp->attr.subroutine;
+      proc->attr.use_assoc = tmp->attr.use_assoc;
+      proc->ts = tmp->ts;
+      proc->result = tmp->result;
+    }
+ }
+
       /* Check for F08:C465.  */
       if ((!proc->attr.subroutine && !proc->attr.function)
   || (proc->attr.proc != PROC_MODULE
       && proc->attr.if_source != IFSRC_IFBODY)
   || proc->attr.abstract)
  {
-  gfc_error ("%qs must be a module procedure or an external procedure with"
-    " an explicit interface at %L", proc->name, &where);
+  gfc_error ("%qs must be a module procedure or an external "
+     "procedure with an explicit interface at %L",
+     proc->name, &where);
   goto error;
  }
     }
--
Steve
Reply | Threaded
Open this post in threaded view
|

Re: type-bound procedures, use association, and rogue namespaces

Steve Kargl
On Thu, Jun 13, 2019 at 01:55:28PM -0700, Steve Kargl wrote:

>
> Well, this feels like a kludge, but appears to work.  Anyone
> who is familiar with type-bound procedures have a better
> idea?
>
> Index: gcc/fortran/resolve.c
> ===================================================================
> --- gcc/fortran/resolve.c (revision 272259)
> +++ gcc/fortran/resolve.c (working copy)
> @@ -13536,14 +13537,34 @@ resolve_typebound_procedure (gfc_symtree* stree)
>      }
>    else
>      {
> +      /* If proc has not been resolved at this point, proc->name may
> + actually be a USE associated entity. See PR fortran/89647. */
> +      if (!proc->resolved
> +  && proc->attr.function == 0 && proc->attr.subroutine == 0)
> + {
> +  gfc_symbol *tmp;
> +  gfc_find_symbol (proc->name, gfc_current_ns->parent, 1, &tmp);
> +  if (tmp->attr.use_assoc)
> +    {
> +      proc->module = tmp->module;
> +      proc->attr.proc = tmp->attr.proc;
> +      proc->attr.function = tmp->attr.function;
> +      proc->attr.subroutine = tmp->attr.subroutine;
> +      proc->attr.use_assoc = tmp->attr.use_assoc;
> +      proc->ts = tmp->ts;
> +      proc->result = tmp->result;
> +    }
> + }
> +

Regression tests cleanly.  I wait a few days before submitting
this as an actually fix.

--
Steve