https://gcc.gnu.org/g:1a2de01fbac64f97fed6f63ff655b13bff831877
commit r17-2028-g1a2de01fbac64f97fed6f63ff655b13bff831877 Author: Paul Thomas <[email protected]> Date: Tue Jun 30 10:39:57 2026 +0100 Fortran: Fix memory leak found in pdt_86.f03 [PR121972] Followup on memory leaks found using -fsanitize=address in existing test cases. Co-authored-by: Jerry DeLisle <[email protected]> PR fortran/121972 gcc/fortran/ * decl.cc (gfc_get_pdt_instance): A PDT that has a derived type component, which has allocatable components, must be marked as having allocatable components. * resolve.cc (gfc_resolve_ref): Initialize last_pdt from the base symbol's declared type when the expression type is not a PDT. gcc/testsuite/ * gfortran.dg/pdt_86.f03: Add tree dump for counts of frees and mallocs (41 & 31 respectively). * gfortran.dg/pdt_86_reduced.f90: New test to check that the non-PDT version of the leak has gone. Diff: --- gcc/fortran/decl.cc | 4 +++- gcc/fortran/resolve.cc | 7 ++++++- gcc/testsuite/gfortran.dg/pdt_86.f03 | 3 +++ gcc/testsuite/gfortran.dg/pdt_86_reduced.f90 | 26 ++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index 63941edebd9a..6dad9d9791a4 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -4626,7 +4626,9 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, } } - if (c2->attr.allocatable) + if (c2->attr.allocatable + || (c2->ts.type == BT_DERIVED && c2->ts.u.derived + && c2->ts.u.derived->attr.alloc_comp && !c2->attr.pointer)) instance->attr.alloc_comp = 1; } else if (!(c2->attr.pdt_kind || c2->attr.pdt_len || c2->attr.pdt_string diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index 12502f950b3e..9eb022d608d8 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -6164,7 +6164,12 @@ gfc_resolve_ref (gfc_expr *expr) n_components = 0; array_ref = NULL; - if (expr->expr_type == EXPR_VARIABLE && IS_PDT (expr)) + /* Use the declared type of the base symbol to initialize last_pdt when the + expression is not itself a PDT. This matters for ASSOCIATE variables whose + component reference may still point to a PDT template. */ + if (expr->expr_type == EXPR_VARIABLE + && (IS_PDT (expr) + || (expr->ref && expr->symtree && IS_PDT (expr->symtree->n.sym)))) last_pdt = expr->symtree->n.sym->ts.u.derived; for (ref = expr->ref; ref; ref = ref->next) diff --git a/gcc/testsuite/gfortran.dg/pdt_86.f03 b/gcc/testsuite/gfortran.dg/pdt_86.f03 index 6e7798ecfbae..fe7057cd1dda 100644 --- a/gcc/testsuite/gfortran.dg/pdt_86.f03 +++ b/gcc/testsuite/gfortran.dg/pdt_86.f03 @@ -1,4 +1,5 @@ ! { dg-do run } +! { dg-options "-fdump-tree-original" } ! ! Test the fix for PR122902. Line 47 gave "free(): invalid pointer". ! @@ -55,3 +56,5 @@ end submodule if (allocated(input_output_pairs)) deallocate(input_output_pairs) if (allocated(mini_batch)) deallocate(mini_batch) end +! { dg-final { scan-tree-dump-times "__builtin_malloc" 31 "original" } } +! { dg-final { scan-tree-dump-times "__builtin_free" 41 "original" } } diff --git a/gcc/testsuite/gfortran.dg/pdt_86_reduced.f90 b/gcc/testsuite/gfortran.dg/pdt_86_reduced.f90 new file mode 100644 index 000000000000..608a1bbb14c4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pdt_86_reduced.f90 @@ -0,0 +1,26 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! Check the fix for the memory leak in pdt_77.f03. This test is a reduced +! version of the original that isolates the source of the leak. Note that +! the leak is not PDT specific. +! +module input_output_pair_m + implicit none + type tensor_t ! No longer a PDT! + real(kind(1e0)), allocatable :: values_(:) + end type +end module + + use input_output_pair_m + call test +contains + subroutine test + implicit none + type(tensor_t), allocatable :: inputs(:) + integer :: i + inputs = [(tensor_t([real(i)]), i=1,2)] ! Leaked 8 bytes in 2 blocks. + end +end +! { dg-final { scan-tree-dump-times "__builtin_malloc" 7 "original" } } +! { dg-final { scan-tree-dump-times "__builtin_free" 8 "original" } }
