bug16-mold-loses-len.f90 failed to give the correct result because
ALLOCATE with MOLD= did not propagate the LEN parameter.

The ChangeLog provides quite enough explanation of what the patch does.

Passes regtesting on FC44/x86_64. OK for mainline.

Cheers

Paul
From 7698fcb427b164ee9491cd9333a67555f5d74de0 Mon Sep 17 00:00:00 2001
From: Paul Thomas <[email protected]>
Date: Wed, 7 Oct 2026 11:52:44 +0100
Subject: [PATCH] Fortran: [meta-bug] [PDT] Parameterized derived type errors
 [PR82173]

2026-10-07  Paul Thomas  <[email protected]>

gcc/fortran
	PR fortran/82173
	* trans-decl.cc (gfc_trans_deferred_vars): If a PDT procedure
	result has no default initializer or it is in a submodule then
	allocate the parameterized components using its param_list.
	* trans-stmt.cc (gfc_trans_allocate): If a PDT MOLD expr3 is a
	variable, use the symbol's param_list. Assert that there is a
	param_list.

gcc/testsuite/
	PR fortran/82173
	* gfortran.dg/pdt_bug16.f90: New test.
---
 gcc/fortran/trans-decl.cc               |  4 +++-
 gcc/fortran/trans-stmt.cc               |  6 +++++
 gcc/testsuite/gfortran.dg/pdt_bug16.f90 | 31 +++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pdt_bug16.f90

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 44e8b8dde76..4881bb5bbe9 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5071,7 +5071,9 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
 
   if (sym && !sym->attr.allocatable && !sym->attr.pointer
       && sym->attr.referenced
-      && IS_PDT (sym) && !gfc_has_default_initializer (sym->ts.u.derived))
+      && IS_PDT (sym)
+      && (!gfc_has_default_initializer (sym->ts.u.derived)
+	  || proc_sym->attr.used_in_submodule))
     {
       gfc_init_block (&tmpblock);
       tmp = gfc_allocate_pdt_comp (sym->ts.u.derived,
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 9ad8342605a..67f8bfda2f2 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -7705,10 +7705,16 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
 
 	  if (code->expr3 && code->expr3->param_list)
 	    param_list = code->expr3->param_list;
+	  else if (code->expr3 && code->expr3->mold
+		   && code->expr3->expr_type == EXPR_VARIABLE)
+	    param_list = code->expr3->symtree->n.sym->param_list;
 	  else if (expr->param_list)
 	    param_list = expr->param_list;
 	  else
 	    param_list = expr->symtree->n.sym->param_list;
+
+	  gcc_assert (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
diff --git a/gcc/testsuite/gfortran.dg/pdt_bug16.f90 b/gcc/testsuite/gfortran.dg/pdt_bug16.f90
new file mode 100644
index 00000000000..1b457620568
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_bug16.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+! ALLOCATE with MOLD= did not propagate the LEN parameter; SOURCE= does.
+! See attachment to PR82173 comment 10 - ~/reducers/bug16-mold-loses-len.f90
+program p
+  type :: t(n)
+    integer, len :: n = 1
+    integer :: v(n)
+  end type
+  type(t(:)), allocatable :: viaSource, viaMold
+  type(t(5)) :: src1
+  type(t(7)) :: src2
+  src1%v = 1
+  src2%v = 2
+  allocate (viaSource, source=src1)
+  allocate (viaMold, mold=src1)
+  if (viaSource%n /= viaMold%n) stop 1
+  if (size (viaSource%v, 1) /= size (viaMold%v, 1)) stop 2
+!
+! Do it again with a different value for n
+!
+  deallocate (viaSource, viaMold)
+  allocate (viaSource, source=src2)
+  allocate (viaMold, mold=src2)
+  viaMold%v = 2
+  if (viaSource%n /= 7) stop 3
+  if (viaSource%n /= viaMold%n) stop 4
+  if (size (viaMold%v, 1) /= 7) stop 5
+  if (size (viaSource%v, 1) /= size (viaMold%v, 1)) stop 6
+  if (sum (viaSource%v) /= sum (viaMold%v)) stop 7
+  deallocate (viaSource, viaMold)
+end program
-- 
2.55.0

Reply via email to