[PATCH] PR125529 ICE in DO CONCURRENT with DEFAULT(NONE) inside, ASSOCIATE

Jerry D <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
This one is straightforward.

See attached.

Regression tested on x86_64.

OK for mainline? and then backport to 16.

Regards,

Jerry

---
fortran: ICE in DO CONCURRENT with DEFAULT(NONE) inside ASSOCIATE

Two bugs in check_default_none_expr caused a segfault when a DO CONCURRENT
with inline type-spec iterators (e.g. "integer :: i = 1:10") contained an
ASSOCIATE construct.

Bug 1: sym->ns->code was used to locate the ext.concur.forall_iterator
list.  When a symbol's namespace is an ASSOCIATE body, sym->ns->code is an
EXEC_BLOCK node, not the DO CONCURRENT node; reading ext.concur from it
interprets the wrong union member and yields a garbage pointer.  Fix: use
d->code instead, the DO CONCURRENT gfc_code node passed through the walker's
data parameter, which is always the correct node.

Bug 2: inline type-spec iterators are shadow iterators, stored internally
with a leading underscore prepended to the name.  The comparison of the
iterator's symtree name against the user-visible sym->name must skip that
underscore by advancing iter_name one character when iter->shadow is set.

PR fortran/125529

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

	PR fortran/125529
	* resolve.cc (check_default_none_expr): Use d->code instead of
	sym->ns->code to locate the DO CONCURRENT forall_iterator list,
	avoiding a wrong-union-member read when the symbol's namespace is
	an ASSOCIATE body.  Skip leading underscore when comparing iterator
	names for shadow iterators.

gcc/testsuite/ChangeLog:

	PR fortran/125529
	* gfortran.dg/do_concurrent_assoc_default_none.f90: New test.
PR125529-do-concurrent-default-none.patch (text/x-patch, 4.9 KB)
From d184c3c93f3de6132b8ac466b3ecb0f0a33dda4c Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Wed, 27 May 2026 21:00:19 -0700
Subject: [PATCH] fortran: ICE in DO CONCURRENT with DEFAULT(NONE) inside
 ASSOCIATE

Two bugs in check_default_none_expr caused a segfault when a DO CONCURRENT
with inline type-spec iterators (e.g. "integer :: i = 1:10") contained an
ASSOCIATE construct.

Bug 1: sym->ns->code was used to locate the ext.concur.forall_iterator
list.  When a symbol's namespace is an ASSOCIATE body, sym->ns->code is an
EXEC_BLOCK node, not the DO CONCURRENT node; reading ext.concur from it
interprets the wrong union member and yields a garbage pointer.  Fix: use
d->code instead, the DO CONCURRENT gfc_code node passed through the walker's
data parameter, which is always the correct node.

Bug 2: inline type-spec iterators are shadow iterators, stored internally
with a leading underscore prepended to the name.  The comparison of the
iterator's symtree name against the user-visible sym->name must skip that
underscore by advancing iter_name one character when iter->shadow is set.

PR fortran/125529

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

	PR fortran/125529
	* resolve.cc (check_default_none_expr): Use d->code instead of
	sym->ns->code to locate the DO CONCURRENT forall_iterator list,
	avoiding a wrong-union-member read when the symbol's namespace is
	an ASSOCIATE body.  Skip leading underscore when comparing iterator
	names for shadow iterators.

gcc/testsuite/ChangeLog:

	PR fortran/125529
	* gfortran.dg/do_concurrent_assoc_default_none.f90: New test.
---
 gcc/fortran/resolve.cc                        | 24 ++++++++-----
 .../do_concurrent_assoc_default_none.f90      | 35 +++++++++++++++++++
 2 files changed, 51 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/do_concurrent_assoc_default_none.f90

diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index df91671e171..b9078fd8722 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -8597,15 +8597,23 @@ check_default_none_expr (gfc_expr **e, int *, void *data)
 	      ns2 = ns2->parent;
 	    }
 
-	  /* A DO CONCURRENT iterator cannot appear in a locality spec.  */
-	  if (sym->ns->code->ext.concur.forall_iterator)
+	  /* A DO CONCURRENT iterator cannot appear in a locality spec.
+	     Use d->code (the DO CONCURRENT node) rather than sym->ns->code,
+	     which may be a different code type (e.g. EXEC_ASSOCIATE) whose
+	     ext union would be read incorrectly.  */
+	  for (gfc_forall_iterator *iter = d->code->ext.concur.forall_iterator;
+	       iter; iter = iter->next)
 	    {
-	      gfc_forall_iterator *iter
-		= sym->ns->code->ext.concur.forall_iterator;
-	      for (; iter; iter = iter->next)
-		if (iter->var->symtree
-		    && strcmp(sym->name, iter->var->symtree->name) == 0)
-		  return 0;
+	      if (!iter->var || !iter->var->symtree)
+		continue;
+	      const char *iter_name = iter->var->symtree->name;
+	      /* Shadow iterators (from inline type-spec: integer :: i = ...)
+		 store the iterator with a leading underscore internally; the
+		 user-visible name does not have the underscore.  */
+	      if (iter->shadow)
+		iter_name++;
+	      if (strcmp (sym->name, iter_name) == 0)
+		return 0;
 	    }
 
 	  /* A named constant is not a variable, so skip test.  */
diff --git a/gcc/testsuite/gfortran.dg/do_concurrent_assoc_default_none.f90 b/gcc/testsuite/gfortran.dg/do_concurrent_assoc_default_none.f90
new file mode 100644
index 00000000000..f1cb2718907
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_concurrent_assoc_default_none.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-std=f2018" }
+!
+! PR fortran/125515
+! DO CONCURRENT with inline type-spec iterators and DEFAULT(NONE) inside an
+! ASSOCIATE block used to ICE (segfault in check_default_none_expr).  The
+! bug was that sym->ns->code was used instead of d->code to locate the
+! forall_iterator list; for symbols in an ASSOCIATE or enclosing procedure
+! namespace the wrong union member was read, giving a garbage pointer.
+! Additionally, shadow iterators store their name with a leading underscore
+! internally, so the comparison against user-visible names must strip it.
+
+subroutine test_associate_default_none (a, b)
+  implicit none
+  integer, intent(in)  :: a(10,10)
+  integer, intent(out) :: b(10,10)
+  do concurrent (integer :: i = 1:10, j = 1:10) &
+      default(none) shared(a, b)
+    associate (tmp => a(i,j))
+      b(i,j) = tmp + 1
+    end associate
+  end do
+end subroutine
+
+! Verify that a genuinely missing variable still gets an error.
+subroutine test_missing_var (a, b, c)
+  implicit none
+  integer, intent(in)  :: a(10,10), c
+  integer, intent(out) :: b(10,10)
+  do concurrent (integer :: i = 1:10, j = 1:10) &
+      default(none) shared(a, b)
+    ! { dg-error "not specified in a locality spec" "" { target *-*-* } .-1 }
+    b(i,j) = a(i,j) + c   ! { dg-error "not specified in a locality spec" }
+  end do
+end subroutine
-- 
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.