see attached patch file.

This fixes a breakage from the previous fix for 125528.

Regression tested on x86_64.

OK for mainline and later backport.

Note when backported this needs to go along with 125528.


Regards,

Jerry

---

fortran: ICE for ASSOCIATE selector that is an overloaded
 intrinsic operator

Add a fallback branch in match_association_list that, for any remaining
unresolved EXPR_OP selector with BT_UNKNOWN type, calls gfc_extend_expr
to resolve the overloaded operator to its function call early, so the
associate name receives a usable type before the body is parsed.  The
INTRINSIC_USER path is unchanged.

Assisted by: Claude Sonnet 4.6

        PR fortran/125650

gcc/fortran/ChangeLog:

        * match.cc (match_association_list): Handle ASSOCIATE selectors
        that are overloaded intrinsic operator expressions by extending
        them with gfc_extend_expr at parse time, so the associate name is
        typed before the construct body is parsed.

gcc/testsuite/ChangeLog:

        * gfortran.dg/associate_81.f90: New test.
---
From 62f310364887859136ce9b45d1a39250f8b6d9dc Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Tue, 9 Jun 2026 09:46:30 -0700
Subject: [PATCH] fortran: ICE for ASSOCIATE selector that is an overloaded
 intrinsic operator

Add a fallback branch in match_association_list that, for any remaining
unresolved EXPR_OP selector with BT_UNKNOWN type, calls gfc_extend_expr
to resolve the overloaded operator to its function call early, so the
associate name receives a usable type before the body is parsed.  The
INTRINSIC_USER path is unchanged.

Assisted by: Claude Sonnet 4.6

	PR fortran/125650

gcc/fortran/ChangeLog:

	* match.cc (match_association_list): Handle ASSOCIATE selectors
	that are overloaded intrinsic operator expressions by extending
	them with gfc_extend_expr at parse time, so the associate name is
	typed before the construct body is parsed.

gcc/testsuite/ChangeLog:

	* gfortran.dg/associate_81.f90: New test.
---
 gcc/fortran/match.cc                       | 15 ++++++++
 gcc/testsuite/gfortran.dg/associate_81.f90 | 44 ++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/associate_81.f90

diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 614d4dab152..0abb3231971 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -2326,6 +2326,21 @@ match_association_list (bool for_change_team = false)
 	  else
 	    gfc_free_expr (tmp);
 	}
+      else if (newAssoc->target->ts.type == BT_UNKNOWN
+	       && newAssoc->target->expr_type == EXPR_OP)
+	{
+	  /* The selector is an unresolved expression involving an overloaded
+	     intrinsic operator (e.g. a `+' bound via an explicit interface
+	     to a function returning CHARACTER).  Try to extend it now, the
+	     same way the type-bound user-defined operator case above does
+	     for INTRINSIC_USER, so the associate name gets a usable type
+	     before the body of the ASSOCIATE construct is parsed.  */
+	  gfc_expr *tmp = gfc_copy_expr (newAssoc->target);
+	  if (gfc_extend_expr (tmp) == MATCH_YES)
+	    gfc_replace_expr (newAssoc->target, tmp);
+	  else
+	    gfc_free_expr (tmp);
+	}
 
       /* The `variable' field is left blank for now; because the target is not
 	 yet resolved, we can't use gfc_has_vector_subscript to determine it
diff --git a/gcc/testsuite/gfortran.dg/associate_81.f90 b/gcc/testsuite/gfortran.dg/associate_81.f90
new file mode 100644
index 00000000000..a691aee902c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_81.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+!
+! PR fortran/125650
+!
+! Verify that an ASSOCIATE selector that is an overloaded intrinsic operator
+! expression (here a CHARACTER-returning `+', bound via an explicit
+! interface) is extended to a function call early enough that the
+! associate name receives a known type before the body of the ASSOCIATE
+! construct is parsed.  Previously the associate name stayed untyped,
+! a substring reference to it was matched incorrectly, and the wrong
+! reference reached the back end, causing an ICE in trans-expr.cc.
+
+module associate_81_m
+  implicit none
+
+  interface operator(+)
+    module procedure concat
+  end interface
+
+contains
+
+  function concat (dd1, dd2)
+    implicit none
+    character(len = 8) :: concat
+    character(len = 3), intent(in) :: dd1
+    character(len = 5), intent(in) :: dd2
+    concat = dd1 // dd2
+  end function
+
+end module
+
+program associate_81
+  use associate_81_m
+  implicit none
+
+  character(len = 3) :: arg1 = 'aaa'
+  character(len = 5) :: arg2 = 'ccccc'
+
+  associate (aa => arg1, bb => arg2, cc => arg1 + arg2)
+    if (cc /= 'aaaccccc') stop 1
+    if (cc(3:5) /= 'acc') stop 2
+  end associate
+
+end program
-- 
2.54.0

Reply via email to