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
