At first this PR looked as if it was going to be one of those horrible
typebound procedure/operator tangles. However, it turned out that this was
entirely down to the attempt  to extract the specific procedure for the
ASSOCIATE name during parsing. Returning NULL before expression resolution
fixed the problem.

Regtests fine - OK for mainline? I am inclined to backport, since the fix
is both simple and, at worst, defers the ICE. OK?

Paul

Attachment: Change.Logs
Description: Binary data

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index f74fbf0f6e5..d08f683498d 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 00000000000..c7c461a5cb6
--- /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

Reply via email to