https://gcc.gnu.org/g:ead967d92aee51eaa015148cdca94c5e45af236f
commit r15-9983-gead967d92aee51eaa015148cdca94c5e45af236f Author: Paul Thomas <pa...@gcc.gnu.org> Date: Wed Jul 16 06:16:57 2025 +0100 Fortran: Fix ICE in ASSOCIATE with user defined operator [PR121060] 2025-07-16 Paul Thomas <pa...@gcc.gnu.org> gcc/fortran PR fortran/121060 * interface.cc (matching_typebound_op): Defer determination of specific procedure until resolution by returning NULL. gcc/testsuite/ PR fortran/121060 * gfortran.dg/associate_75.f90: New test. (cherry picked from commit 82e912344d28cf1a69e5f8e047203ea7eb625302) Diff: --- gcc/fortran/interface.cc | 7 +++++ gcc/testsuite/gfortran.dg/associate_75.f90 | 50 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc index f74fbf0f6e58..d08f683498d1 100644 --- a/gcc/fortran/interface.cc +++ b/gcc/fortran/interface.cc @@ -4781,6 +4781,13 @@ matching_typebound_op (gfc_expr** tb_base, gfc_actual_arglist* argcopy; bool matches; + /* If expression matching comes here during parsing, eg. when + parsing ASSOCIATE, generic TBPs have not yet been resolved + and g->specific will not have been set. Wait for expression + resolution by returning NULL. */ + if (!g->specific && !gfc_current_ns->resolved) + return NULL; + gcc_assert (g->specific); if (g->specific->error) continue; diff --git a/gcc/testsuite/gfortran.dg/associate_75.f90 b/gcc/testsuite/gfortran.dg/associate_75.f90 new file mode 100644 index 000000000000..c7c461a5cb65 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_75.f90 @@ -0,0 +1,50 @@ +! { dg-do run } +! +! Test fix for PR121060. +! +! Contributed by Damian Rouson <damian@archaeologic.codes> +! +module subdomain_m + implicit none + + type subdomain_t + real :: s_ = 99. + contains + generic :: operator(.laplacian.) => laplacian + procedure laplacian + end type + +contains + + function laplacian(rhs) + class(subdomain_t), intent(in) :: rhs + type(subdomain_t) laplacian + laplacian%s_ = rhs%s_ + 42 + end function + +end module + + use subdomain_m + implicit none + + type operands_t + real :: s_ + end type + + type(subdomain_t) phi + type(operands_t) operands + + associate(laplacian_phi => .laplacian. phi) ! ICE because specific not found. + operands = approximates(laplacian_phi%s_) + end associate + + if (int (operands%s_) /= 42) stop 1 +contains + + function approximates(actual) + real actual + type(operands_t) approximates + approximates%s_ = actual - 99 + end function + +end