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