Hi all, the attached patch fixes a runtime memory leak with procedure-pointer components (PPCs). gfortran correctly deallocates scalar allocatable function results (also for procedure pointers), but fails to do so for PPCs, which is cured by my patch.
[Note: Since gfortran translates any type-bound procedure call into a PPC call internally, the patch also cures memory leaks with TBPs.] It regtests cleanly on x86_64-linux-gnu. Ok for trunk? Cheers, Janus 2017-06-15 Janus Weil <ja...@gcc.gnu.org> PR fortran/70983 * trans-expr.c (gfc_conv_procedure_call): Deallocate the result of scalar allocatable procedure-pointer components. 2017-06-15 Janus Weil <ja...@gcc.gnu.org> PR fortran/70983 * gfortran.dg/proc_ptr_comp_51.f90: New test.
Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (revision 249130) +++ gcc/fortran/trans-expr.c (working copy) @@ -6132,7 +6132,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * after use. This necessitates the creation of a temporary to hold the result to prevent duplicate calls. */ if (!byref && sym->ts.type != BT_CHARACTER - && sym->attr.allocatable && !sym->attr.dimension && !comp) + && ((sym->attr.allocatable && !sym->attr.dimension && !comp) + || (comp && comp->attr.allocatable && !comp->attr.dimension))) { tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); gfc_add_modify (&se->pre, tmp, se->expr);
! { dg-do compile } ! ! PR 80983: [F03] memory leak when calling procedure-pointer component with allocatable result ! ! Contributed by Janus Weil <ja...@gcc.gnu.org> program test implicit none type :: concrete_type procedure (alloc_integer), pointer, nopass :: alloc end type procedure (alloc_integer), pointer :: pp type(concrete_type) :: concrete print *, alloc_integer() ! case #1: plain function pp => alloc_integer print *, pp() ! case #2: procedure pointer concrete % alloc => alloc_integer print *, concrete % alloc() ! case #3: procedure-pointer component contains function alloc_integer() result(res) integer, allocatable :: res allocate(res, source=13) end function end ! { dg-final { scan-tree-dump-times "__builtin_free" 3 "original" } }