See the attached patch. This fixes a regression related to the fix for PR126950.

Regression tested on x86_64.

I also did a fuzz variation on this to check for any other breakages. None were found.

I plan to commit this tomorrow. It is fairly simple.

Regards,

Jerry

---


fortran: [PR127671] Create the span of a dummy in its owning
 function

The span variable of a span addressed dummy array was always added to the
function being translated.  When the dummy was first referenced from a
contained procedure it ended up there instead of in the host, which loads
it on entry, and tree-nested ICEd.

Assisted-by: Claude Opus 5.5

        PR fortran/127671

gcc/fortran/ChangeLog:

        * trans-decl.cc (gfc_build_dummy_array_decl): Create the span
        variable with create_index_var, in the function that owns the
        dummy.

gcc/testsuite/ChangeLog:

        * gfortran.dg/target_dummy_span_3.f90: New test.
---
From 69234786d75f790dc5c99c5a85fd4d7a5d07828f Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Tue, 29 Sep 2026 15:40:23 -0700
Subject: [PATCH] fortran: [PR127671] Create the span of a dummy in its owning
 function

The span variable of a span addressed dummy array was always added to the
function being translated.  When the dummy was first referenced from a
contained procedure it ended up there instead of in the host, which loads
it on entry, and tree-nested ICEd.

Assisted-by: Claude Opus 5.5

	PR fortran/127671

gcc/fortran/ChangeLog:

	PR fortran/127671
	* trans-decl.cc (gfc_build_dummy_array_decl): Create the span
	variable with create_index_var, in the function that owns the
	dummy.

gcc/testsuite/ChangeLog:

	PR fortran/127671
	* gfortran.dg/target_dummy_span_3.f90: New test.
---
 gcc/fortran/trans-decl.cc                     | 13 +++---
 .../gfortran.dg/target_dummy_span_3.f90       | 43 +++++++++++++++++++
 2 files changed, 51 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/target_dummy_span_3.f90

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index f27fe9fd219..9aebc7466df 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -1409,6 +1409,10 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
 
   GFC_DECL_SAVED_DESCRIPTOR (decl) = dummy;
 
+  bool in_parent_function
+    = sym->ns->proc_name->backend_decl != current_function_decl
+      && !sym->attr.contained;
+
   /* The elements of the actual argument can be spaced by more than the
      element size, in which case they are addressed by the span of the
      descriptor.  Create the variable holding it here, since the body is
@@ -1420,15 +1424,14 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
       else if (gfc_is_span_addressed_dummy (sym))
 	{
 	  GFC_DECL_PTR_ARRAY_P (decl) = 1;
-	  GFC_DECL_SPAN (decl) = gfc_create_var (gfc_array_index_type, "span");
+	  GFC_DECL_SPAN (decl) = create_index_var ("span", in_parent_function);
 	}
     }
 
-  if (sym->ns->proc_name->backend_decl == current_function_decl
-      || sym->attr.contained)
-    gfc_add_decl_to_function (decl);
-  else
+  if (in_parent_function)
     gfc_add_decl_to_parent_function (decl);
+  else
+    gfc_add_decl_to_function (decl);
 
   return decl;
 }
diff --git a/gcc/testsuite/gfortran.dg/target_dummy_span_3.f90 b/gcc/testsuite/gfortran.dg/target_dummy_span_3.f90
new file mode 100644
index 00000000000..5f807253750
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/target_dummy_span_3.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! PR 127671
+! Span of a TARGET dummy referenced only from a contained procedure.
+
+module m
+  implicit none
+  type t
+     integer :: n = 0
+  end type t
+  type w
+     real :: pad(3)
+     type(t) :: x
+  end type w
+contains
+  subroutine host (a, s, s2)
+    type(t), intent(in), target :: a(:)
+    integer, intent(out) :: s, s2
+    s = 0
+    call inner ()
+    s2 = sum (a%n)
+  contains
+    subroutine inner ()
+      integer :: i
+      do i = 1, size (a)
+        s = s + a(i)%n * i
+      end do
+    end subroutine inner
+  end subroutine host
+end module m
+program p
+  use m
+  implicit none
+  type(w) :: v(6)
+  integer :: i, s, s2
+  do i = 1, 6
+    v(i)%x%n = 10 * i
+  end do
+  call host (v(::2)%x, s, s2)
+  if (s /= 10*1 + 30*2 + 50*3) stop 1
+  if (s2 /= 90) stop 2
+  call host (v%x, s, s2)
+  if (s2 /= 210) stop 3
+end program p
-- 
2.55.0

Reply via email to