https://gcc.gnu.org/g:f4d32f612a3c43e9d0a861b7dae7bb67139c9ab0

commit r17-4803-gf4d32f612a3c43e9d0a861b7dae7bb67139c9ab0
Author: Jerry DeLisle <[email protected]>
Date:   Tue Sep 29 15:40:23 2026 -0700

    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.

Diff:
---
 gcc/fortran/trans-decl.cc                         | 13 ++++---
 gcc/testsuite/gfortran.dg/target_dummy_span_3.f90 | 43 +++++++++++++++++++++++
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 2b7ef12c1a82..a614e71eced2 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -1406,6 +1406,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
@@ -1417,15 +1421,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 000000000000..5f807253750e
--- /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

Reply via email to