https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120049

--- Comment #23 from kargls at comcast dot net ---
On 5/9/25 17:50, jvdelisle at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120049
> 
> Jerry DeLisle <jvdelisle at gcc dot gnu.org> changed:
> 
>             What    |Removed                     |Added
> ----------------------------------------------------------------------------
>             Assignee|unassigned at gcc dot gnu.org      |jvdelisle at gcc dot 
> gnu.org
>               Status|NEW                         |ASSIGNED
> 
> --- Comment #21 from Jerry DeLisle <jvdelisle at gcc dot gnu.org> ---
> I have been digging in on this further. The basic types are defined in
> libgfortran.h as shown here:
> 
> typedef enum
> { BT_UNKNOWN = 0, BT_INTEGER, BT_LOGICAL, BT_REAL, BT_COMPLEX,
>    BT_DERIVED, BT_CHARACTER, BT_CLASS, BT_PROCEDURE, BT_HOLLERITH, BT_VOID,
>    BT_ASSUMED, BT_UNION, BT_BOZ, BT_UNSIGNED
> }
> bt;
> 
> I have been checking for each one of these and building a test case. Obviously
> our original checks based on (ts.type != BT_DERIVED) is too broad and short
> circuiting based on the expr_type is too narrow. The simpler types BT_INTEGER,
> BT_LOGICAL, BT_REAL, BT_COMPLEX, BT_CHARACTER, BT_HOLLERITH, BT_BOZ,
> BT_UNSIGNED I think can be rejected
> 
> 
> The BT_CLASS, BT_PROCEDURE, BT_ASSUMED, BT_UNION seem to not make sense to me
> either. Steve, what do yo think about these last types. I can easily reject
> them as well.
> 
> Look at my WIP patch now I am pretty sure I will be able to re-factor this 
> code
> and I will work on this while waiting for further feedback on this.

I've thought a bit about this, but have no solution, yet.

First, I think that the underlying issue is how C_LOC is written
into a user's module.  If you have

    use iso_c_binding
    type(c_ptr), target :: x, y
    y = c_loc(x)
    print *, c_associated(c_loc(x), y)
    end

then you have

(gdb) p *c_ptr_1
$2 = {expr_type = EXPR_FUNCTION, ts = {type = BT_DERIVED, kind = 0,
       u = {derived = 0x804042780, cl = 0x804042780, pad = 67381120},
       interface = 0x0, is_c_interop = 1, is_iso_c = 0,
       f90_type = BT_VOID,


If iso_c_binding was used in module bar, then C_LOC is in the module
name space.

    % cat bar.f90
    module bar
      use iso_c_binding
    end module

    % cat u.f90
    use bar
    type(c_ptr) x
    print *, c_associated(x)
    end

One see that the type is BT_VOID

$3 = {expr_type = EXPR_FUNCTION, ts = {type = BT_VOID, kind = 0,
       u = {derived = 0x0, cl = 0x0, pad = 0}, interface = 0x0,
       is_c_interop = 0, is_iso_c = 0, f90_type = BT_UNKNOWN,
       deferred = false,

So, it seems that f90_type=BT_VOID from C_PTR is used when the
information for C_LOC is written into module bar.  One fix might
be to learn why C_LOC written to a user module does not have a
type of C_PTR.

That said, I think we'll need to do something like

   if (c_ptr_1->ts.type == BT_DERIVED)
     {
       /* Check name is c_ptr or c_funptr.  */
       if (!(strcmp (c_ptr_1->ts.u.derived->name, "c_ptr") == 0
             !! strcmp (c_ptr_1->ts.u.derived->name, "c_funptr") == 0))
          error
     }
   else if (c_ptr_1->ts.type == BT_VOID
            && c_ptr_1->expr_type == EXPR_FUNCTION)
     {
       /* Check that function is c_loc of c_funloc */
       if (!(strcmp(c_ptr_1->value.function.isym.name, "c_loc") == 0
             !! strcmp(c_ptr_1->ts.u.derived->name, "c_funloc") == 0))
          error
    }
   else
     error


This will get complicated because clever users will do something like

   ! Type off-top-head, so syntax may be wrong.
   module bar
     use iso_c_binding, only -> aaa => c_ptr, bbb => c_loc
     contain
       function my_loc(x)
        type(aaa) my_loc, x
        my_loc = bbb(x)
       end
   end bar

Reply via email to