of calling the appropriate finalizers, coarray deregistering, and
deallocation of allocatable subcomponents. */
-static void
+static bool
finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
gfc_namespace *sub_ns)
gfc_was_finalized *f;
if (!comp_is_finalizable (comp))
- return;
+ return false;
/* If this expression with this component has been finalized
already in this namespace, there is nothing to do. */
for (f = sub_ns->was_finalized; f; f = f->next)
{
if (f->e == expr && f->c == comp)
- return;
+ return false;
}
e = gfc_copy_expr (expr);
final_wrap->ext.actual->next->next = gfc_get_actual_arglist ();
final_wrap->ext.actual->next->next->expr = fini_coarray_expr;
-
-
if (*code)
{
(*code)->next = final_wrap;
else
{
gfc_component *c;
+ bool ret = false;
for (c = comp->ts.u.derived->components; c; c = c->next)
- finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code,
- sub_ns);
- gfc_free_expr (e);
+ ret |= finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray,
+ code, sub_ns);
+ /* Only free the expression, if it has never been used. */
+ if (!ret)
+ gfc_free_expr (e);
}
/* Record that this was finalized already in this namespace. */
sub_ns->was_finalized->e = expr;
sub_ns->was_finalized->c = comp;
sub_ns->was_finalized->next = f;
+ return true;
}
{
gfc_symbol *stat;
gfc_code *block = NULL;
+ gfc_expr *ptr_expr;
if (!ptr)
{
sub_ns);
block = block->next;
+ ptr_expr = gfc_lval_expr_from_sym (ptr);
for (comp = derived->components; comp; comp = comp->next)
{
if (comp == derived->components && derived->attr.extension
&& ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
continue;
- finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
- stat, fini_coarray, &block, sub_ns);
+ finalize_component (ptr_expr, derived, comp, stat, fini_coarray,
+ &block, sub_ns);
if (!last_code->block->next)
last_code->block->next = block;
}
--- /dev/null
+!{ dg-do run }
+
+! PR fortran/120637
+
+! Contributed by Antony Lewis <antony@cosmologist.info>
+! The unused module is needed to trigger the issue of not freeing the
+! memory of second module.
+
+ module MiscUtils
+ implicit none
+
+ contains
+
+ logical function isFloat0(R)
+ class(*), intent(in) :: R
+
+ select type(R)
+ type is (real)
+ isFloat0 = .true.
+ end select
+ end function isFloat0
+
+ end module MiscUtils
+
+ module results3
+ implicit none
+ public
+
+ Type ClTransferData2
+ real, dimension(:,:,:), allocatable :: Delta_p_l_k
+ end type ClTransferData2
+
+ type TCLdata2
+ Type(ClTransferData2) :: CTransScal, CTransTens, CTransVec
+ end type TCLdata2
+
+ type :: CAMBdata2
+ Type(TClData2) :: CLdata2
+ end type
+
+ end module results3
+
+program driver
+ use results3
+ integer i
+ do i=1, 2
+ call test()
+ end do
+
+ contains
+
+ subroutine test
+ implicit none
+ class(CAMBdata2), pointer :: Data
+
+ allocate(CAMBdata2::Data)
+
+ allocate(Data%ClData2%CTransScal%Delta_p_l_k(3, 1000, 1000))
+ allocate(Data%ClData2%CTransVec%Delta_p_l_k(3, 1000, 1000))
+ deallocate(Data)
+
+ end subroutine test
+
+ end program driver
+
+!{ dg-final { cleanup-modules "miscutils results3" } }
+