Finalization depends on the expression, not on the component.
This patch fixes a 8/9/10/11 regression, where finalized types were not finalized (and deallocated), which led to memory leaks. gcc/fortran/ChangeLog: 2020-05-24 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/94361 * class.c (finalize_component): Use expr->finalized instead of comp->finalized. * gfortran.h (gfc_component): Remove finalized member. (gfc_expr): Add it here instead. gcc/testsuite/ChangeLog: 2020-05-24 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/94361 * gfortran.dg/finalize_28.f90: Adjusted free counts. * gfortran.dg/finalize_33.f90: Likewise. * gfortran.dg/finalize_34.f90: Likewise. * gfortran.dg/finalize_35.f90: New test.
This commit is contained in:
parent
dc8c02ca1c
commit
811f902b76
|
@ -921,7 +921,7 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
|
|||
if (!comp_is_finalizable (comp))
|
||||
return;
|
||||
|
||||
if (comp->finalized)
|
||||
if (expr->finalized)
|
||||
return;
|
||||
|
||||
e = gfc_copy_expr (expr);
|
||||
|
@ -1012,6 +1012,7 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
|
|||
}
|
||||
else
|
||||
(*code) = cond;
|
||||
|
||||
}
|
||||
else if (comp->ts.type == BT_DERIVED
|
||||
&& comp->ts.u.derived->f2k_derived
|
||||
|
@ -1051,7 +1052,7 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
|
|||
sub_ns);
|
||||
gfc_free_expr (e);
|
||||
}
|
||||
comp->finalized = true;
|
||||
expr->finalized = 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1107,7 +1107,6 @@ typedef struct gfc_component
|
|||
struct gfc_typebound_proc *tb;
|
||||
/* When allocatable/pointer and in a coarray the associated token. */
|
||||
tree caf_token;
|
||||
bool finalized;
|
||||
}
|
||||
gfc_component;
|
||||
|
||||
|
@ -2218,6 +2217,9 @@ typedef struct gfc_expr
|
|||
/* Set this if the expression came from expanding an array constructor. */
|
||||
unsigned int from_constructor : 1;
|
||||
|
||||
/* Set this if the expression has already been finalized. */
|
||||
unsigned int finalized : 1;
|
||||
|
||||
/* If an expression comes from a Hollerith constant or compile-time
|
||||
evaluation of a transfer statement, it may have a prescribed target-
|
||||
memory representation, and these cannot always be backformed from
|
||||
|
|
|
@ -21,4 +21,4 @@ contains
|
|||
integer, intent(out) :: edges(:,:)
|
||||
end subroutine coo_dump_edges
|
||||
end module coo_graphs
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free" 5 "original" } }
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free" 6 "original" } }
|
||||
|
|
|
@ -116,4 +116,4 @@ contains
|
|||
! (iii) mci_template
|
||||
end program main_ut
|
||||
! { dg-final { scan-tree-dump-times "__builtin_malloc" 17 "original" } }
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free" 19 "original" } }
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free" 20 "original" } }
|
||||
|
|
|
@ -22,4 +22,4 @@ program main
|
|||
use testmodule
|
||||
type(evtlist_type), dimension(10) :: a
|
||||
end program main
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free" 8 "original" } }
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free" 12 "original" } }
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
! { dg-do compile }
|
||||
! { dg-additional-options "-fdump-tree-original" }
|
||||
! PR 94361 - this left open some memory leaks. Original test case by
|
||||
! Antony Lewis.
|
||||
|
||||
module debug
|
||||
private
|
||||
|
||||
Type TypeWithFinal
|
||||
contains
|
||||
FINAL :: finalizer !No leak if this line is commented
|
||||
end type TypeWithFinal
|
||||
|
||||
Type Tester
|
||||
real, dimension(:), allocatable :: Dat
|
||||
Type(TypeWithFinal) :: X
|
||||
end Type Tester
|
||||
|
||||
Type :: TestType2
|
||||
Type(Tester) :: T
|
||||
end type TestType2
|
||||
public Leaker
|
||||
contains
|
||||
|
||||
subroutine Leaker
|
||||
type(TestType2) :: Test
|
||||
|
||||
allocate(Test%T%Dat(1000))
|
||||
end subroutine Leaker
|
||||
|
||||
subroutine finalizer(this)
|
||||
Type(TypeWithFinal) :: this
|
||||
end subroutine finalizer
|
||||
|
||||
end module debug
|
||||
|
||||
|
||||
program run
|
||||
use debug
|
||||
implicit none
|
||||
integer i
|
||||
|
||||
do i=1, 1000
|
||||
call Leaker()
|
||||
end do
|
||||
|
||||
end program run
|
||||
! { dg-final { scan-tree-dump-times "__builtin_free\\ \\(ptr2" 2 "original" } }
|
Loading…
Reference in New Issue