See attached patch.

This fix is also straight forward.

Regression tested on x86_64.

OK for mainline and later backport to 16.

Reagrds,

Jerry

---

When an ASSOCIATE body references inline type-spec iterator,
replace_in_code_recursive lacked a case for EXEC_BLOCK
(associate constructs).  So, it silently skipped both
the ASSOCIATE selector expressions and the body when
replacing shadow iterator references.

Add case EXEC_BLOCK to iterate over each selector's target
expression via replace_in_expr_recursive and recurse into
the body namespace's code list via replace_in_code_recursive.

PR fortran/125532

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

        * resolve.cc (replace_in_code_recursive): Add EXEC_BLOCK case to
        replace shadow iterator references in ASSOCIATE selector expressions
        and the ASSOCIATE body namespace.

gcc/testsuite/ChangeLog:

        * gfortran.dg/do_concurrent_assoc_iter_1.f90: New test.
---
From 39f0b25b48467283c155be5f52484ea11509a521 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Fri, 5 Jun 2026 11:55:29 -0700
Subject: [PATCH] fortran: wrong-code in DO CONCURRENT with ASSOCIATE

When an ASSOCIATE body references inline type-spec iterator,
replace_in_code_recursive lacked a case for EXEC_BLOCK
(associate constructs).  So, it silently skipped both
the ASSOCIATE selector expressions and the body when
replacing shadow iterator references.

Add case EXEC_BLOCK to iterate over each selector's target
expression via replace_in_expr_recursive and recurse into
the body namespace's code list via replace_in_code_recursive.

PR fortran/125532

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

	* resolve.cc (replace_in_code_recursive): Add EXEC_BLOCK case to
	replace shadow iterator references in ASSOCIATE selector expressions
	and the ASSOCIATE body namespace.

gcc/testsuite/ChangeLog:

	* gfortran.dg/do_concurrent_assoc_iter_1.f90: New test.
---
 gcc/fortran/resolve.cc                        | 13 ++++++++++
 .../do_concurrent_assoc_iter_1.f90            | 25 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/do_concurrent_assoc_iter_1.f90

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index b9078fd8722..7fb122a3292 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -12749,6 +12749,19 @@ replace_in_code_recursive (gfc_code *code, gfc_symbol *old_sym, gfc_symtree *new
 	     they'll be handled separately */
 	  break;
 
+	case EXEC_BLOCK:
+	  /* Replace in ASSOCIATE selector expressions and the body.
+	     The body of an EXEC_BLOCK lives in c->ext.block.ns->code, not
+	     c->block->next, so without this case both selectors and body
+	     are silently skipped, leaving shadow iterator references unreplaced
+	     and producing wrong values at runtime.  */
+	  for (gfc_association_list *alist = c->ext.block.assoc;
+	       alist; alist = alist->next)
+	    replace_in_expr_recursive (alist->target, old_sym, new_st);
+	  if (c->ext.block.ns)
+	    replace_in_code_recursive (c->ext.block.ns->code, old_sym, new_st);
+	  break;
+
 	default:
 	  break;
 	}
diff --git a/gcc/testsuite/gfortran.dg/do_concurrent_assoc_iter_1.f90 b/gcc/testsuite/gfortran.dg/do_concurrent_assoc_iter_1.f90
new file mode 100644
index 00000000000..5b7e4f9b205
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_concurrent_assoc_iter_1.f90
@@ -0,0 +1,25 @@
+! { dg-do run }
+! PR fortran/125532
+! DO CONCURRENT with inline type-spec iterator used inside an ASSOCIATE body
+! produced wrong values: replace_in_code_recursive lacked an EXEC_BLOCK case
+! so shadow iterator references were not replaced.
+program do_concurrent_assoc_iter_1
+  implicit none
+  integer :: a(5), b(5)
+  a = 0
+  b = 0
+  ! Iterator k used in the ASSOCIATE selector and in the body.
+  do concurrent (integer :: k = 1:5)
+    associate (sq => k * k)
+      a(k) = sq
+    end associate
+  end do
+  ! Iterator k used only inside the body (not in selector).
+  do concurrent (integer :: k = 1:5)
+    associate (v => k)
+      b(v) = k + 10
+    end associate
+  end do
+  if (any (a /= [1, 4, 9, 16, 25])) stop 1
+  if (any (b /= [11, 12, 13, 14, 15])) stop 2
+end program
-- 
2.54.0

Reply via email to