[PATCH] PR125532 wrong-code in DO CONCURRENT with ASSOCIATE

Jerry D <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
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.
---
PR125532-do-concurrent-assoc-iter.patch (text/x-patch, 3.2 KB)
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.