[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