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
