https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120049
--- Comment #27 from kargls at comcast dot net --- On 5/10/25 06:21, anlauf at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120049 > > --- Comment #26 from anlauf at gcc dot gnu.org --- > Have you tried to move some of the checks *after* the resolution stage? > > The checks in check.cc are invoked rather early. Maybe look into > trans-intrinsic.cc (conv_isocbinding_function)? > The checks in check.cc should still occur, but I think we need something like my WIP. The diff is hard to read, so: /* C_PTR_1 shall be a scalar of type C_PTR or C_FUNPTR. C_PTR_2 (optional) shall be a scalar of the same type as C_PTR_1. In 'A = C_ASSOCIATED(C_LOC(X))' and similar expression where C_LOC is indirectly accessed through a user's module and not directly from ISO_C_BINDING, the */ bool gfc_check_c_associated (gfc_expr *c_ptr_1, gfc_expr *c_ptr_2) { bool saw_c_ptr = false, saw_fun_ptr = false; if (!scalar_check (c_ptr_1, 0)) return false; /* This test might be too restrictive due to renaming as from_intmod might not be set. */ if (c_ptr_1->ts.type == BT_DERIVED && c_ptr_1->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING) { if (c_ptr_1->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR) saw_c_ptr = true; else if (c_ptr_1->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR) saw_c_funptr = true; else goto error1; } else if (c_ptr_1->expr_type == EXPR_FUNCTION && c_ptr_1->ts.type == BT_VOID) { if (c_ptr_1->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR) saw_c_ptr = true; else if (c_ptr_1->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR) saw_c_funptr = true; else goto error1; } else goto error1; if (c_ptr_2 && !scalar_check (c_ptr_2, 1)) return false; if (c_ptr_2 && saw_c_ptr) { if (c_ptr_2->ts.type == BT_DERIVED && c_ptr_2->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING && c_ptr_2->ts.u.derived->intmod_sym_id != ISOCBINDING_PTR) goto erro2; else if (c_ptr_2->expr_type == EXPR_FUNCTION && c_ptr_2->ts.type == BT_VOID) { } else goto error2; } else if (c_ptr_2 && saw_c_funptr) { /* Same type of checking as for C_PTR. */ } else goto error2; return true; error1: gfc_error ("Argument C_PTR_1 at %L to C_ASSOCIATED shall have the " "type TYPE(C_PTR) or TYPE(C_FUNPTR)", &c_ptr_1->where); return false; error2: gfc_error ("Argument C_PTR_2 at %L to C_ASSOCIATED shall have the " "same type as C_PTR_1: %s instead of %s", &c_ptr_1->where, gfc_typename (&c_ptr_1->ts), gfc_typename (&c_ptr_2->ts)); return false; }