See attached patch.

Regression tested on x86_64.

OK for mainline and then backport to 16?

Regards,

Jerry

---

fortran: ALLOCATE of parameterized derived-type array
 initializes only first element

gfc_trans_allocate passed expr->rank to gfc_allocate_pdt_comp and
gfc_deallocate_pdt_comp for array allocations of parameterized derived
types.  For an allocate-shape-spec expression (e.g. "allocate(a(n))"),
expr->rank is 0 even though the symbol is an array; the rank is carried on
the symbol rather than on the allocate expression.  With rank 0 the loop
that initialises each element's allocatable components ran zero times, so
only element zero was initialised.  Subsequent accesses to elements 1..N-1
used garbage pointers and crashed.

Fix: when se.expr is a GFC array descriptor, take the rank from the
descriptor via GFC_TYPE_ARRAY_RANK instead of from expr->rank.  Apply the
same correction to the CLASS path and to the matching deallocate calls in
gfc_trans_deallocate.

PR fortran/125534

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

        PR fortran/125534
        * trans-stmt.cc (gfc_trans_allocate): Use GFC_TYPE_ARRAY_RANK from
        the GFC descriptor type when se.expr is a descriptor, rather than
        expr->rank, for the rank passed to gfc_allocate_pdt_comp.  Apply
        the same fix to the CLASS path.
        (gfc_trans_deallocate): Likewise for gfc_deallocate_pdt_comp.

gcc/testsuite/ChangeLog:

        PR fortran/125534
        * gfortran.dg/pdt_array_alloc_1.f90: New test.
---
From 51e3836f39f884bf1b68866e4fcf12a34716716a Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Fri, 5 Jun 2026 13:19:58 -0700
Subject: [PATCH] fortran: ALLOCATE of parameterized derived-type array
 initializes only first element

gfc_trans_allocate passed expr->rank to gfc_allocate_pdt_comp and
gfc_deallocate_pdt_comp for array allocations of parameterized derived
types.  For an allocate-shape-spec expression (e.g. "allocate(a(n))"),
expr->rank is 0 even though the symbol is an array; the rank is carried on
the symbol rather than on the allocate expression.  With rank 0 the loop
that initialises each element's allocatable components ran zero times, so
only element zero was initialised.  Subsequent accesses to elements 1..N-1
used garbage pointers and crashed.

Fix: when se.expr is a GFC array descriptor, take the rank from the
descriptor via GFC_TYPE_ARRAY_RANK instead of from expr->rank.  Apply the
same correction to the CLASS path and to the matching deallocate calls in
gfc_trans_deallocate.

PR fortran/125534

Assisted by: Claude Sonnet 4.6

gcc/fortran/ChangeLog:

	PR fortran/125534
	* trans-stmt.cc (gfc_trans_allocate): Use GFC_TYPE_ARRAY_RANK from
	the GFC descriptor type when se.expr is a descriptor, rather than
	expr->rank, for the rank passed to gfc_allocate_pdt_comp.  Apply
	the same fix to the CLASS path.
	(gfc_trans_deallocate): Likewise for gfc_deallocate_pdt_comp.

gcc/testsuite/ChangeLog:

	PR fortran/125534
	* gfortran.dg/pdt_array_alloc_1.f90: New test.
---
 gcc/fortran/trans-stmt.cc                     | 30 +++++++++++++++----
 .../gfortran.dg/pdt_array_alloc_1.f90         | 30 +++++++++++++++++++
 2 files changed, 55 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pdt_array_alloc_1.f90

diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 00ddb0629cd..35dcfc1cf29 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -7695,8 +7695,15 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
 	    param_list = expr->param_list;
 	  else
 	    param_list = expr->symtree->n.sym->param_list;
+	  /* For array allocations the allocate-shape-spec expression has
+	     rank 0 even though the symbol is an array.  Use the rank from
+	     the array descriptor when se.expr is a GFC descriptor so that
+	     gfc_allocate_pdt_comp loops over all elements.  */
+	  int pdt_rank = (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
+			  ? GFC_TYPE_ARRAY_RANK (TREE_TYPE (se.expr))
+			  : expr->rank);
 	  tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
-				       expr->rank, param_list);
+				       pdt_rank, param_list);
 	  gfc_add_expr_to_block (&block, tmp);
 	}
       /* Ditto for CLASS expressions.  */
@@ -7708,8 +7715,11 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
 	    param_list = expr->param_list;
 	  else
 	    param_list = expr->symtree->n.sym->param_list;
+	  int pdt_rank = (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
+			  ? GFC_TYPE_ARRAY_RANK (TREE_TYPE (se.expr))
+			  : expr->rank);
 	  tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
-				       se.expr, expr->rank, param_list);
+				       se.expr, pdt_rank, param_list);
 	  gfc_add_expr_to_block (&block, tmp);
 	}
       else if (code->expr3 && code->expr3->mold
@@ -7965,10 +7975,20 @@ gfc_trans_deallocate (gfc_code *code)
       if (expr->ts.type == BT_DERIVED
 	  && ((expr->ts.u.derived->attr.pdt_type && param_list)
 	      || expr->ts.u.derived->attr.pdt_comp))
-	tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
+	{
+	  int pdt_rank = (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
+			  ? GFC_TYPE_ARRAY_RANK (TREE_TYPE (se.expr))
+			  : expr->rank);
+	  tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, pdt_rank);
+	}
       else if (IS_CLASS_PDT (expr) && expr->symtree->n.sym->param_list)
-	tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
-				       se.expr, expr->rank);
+	{
+	  int pdt_rank = (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
+			  ? GFC_TYPE_ARRAY_RANK (TREE_TYPE (se.expr))
+			  : expr->rank);
+	  tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
+					 se.expr, pdt_rank);
+	}
 
       if (tmp)
 	gfc_add_expr_to_block (&se.pre, tmp);
diff --git a/gcc/testsuite/gfortran.dg/pdt_array_alloc_1.f90 b/gcc/testsuite/gfortran.dg/pdt_array_alloc_1.f90
new file mode 100644
index 00000000000..82e745e9ed4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_array_alloc_1.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+! Test that allocating an array of parameterized derived type initializes
+! the allocatable components of ALL elements, not just element 0.
+! PR fortran/125534
+
+module m
+  implicit none
+  integer, parameter :: default_real = kind(0.)
+  type :: tensor_t(k)
+    integer, kind :: k = default_real
+    real(k), allocatable :: values_(:)
+  end type
+end module
+
+program pdt_array_alloc
+  use m
+  implicit none
+  integer, parameter :: n = 5
+  type(tensor_t), allocatable :: a(:)
+  integer :: i
+
+  allocate(a(n))
+  ! Without the fix, only a(1)%values_ was initialized (nullified);
+  ! a(2)..a(n) had garbage pointers and the assignment below would crash.
+  do i = 1, n
+    a(i)%values_ = [real(i), real(i*2)]
+  end do
+
+  if (any(a(3)%values_ /= [3., 6.])) stop 1
+end program
-- 
2.54.0

Reply via email to