This is the mail archive of the mailing list for the GNU Fortran project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [EXTERNAL] Re: [Patch, F03, RFC] FINAL support in 4.8

Hi all,

> Btw, there is an example code for finalization of derived-type
> components in PR 37336 (comment 6). Note that the finalization routine
> is currently not called for this test case ...

the updated version of the patch in the attachment now generates a
call to the finalization routine for the following variant of the
above test case:

module finalizable_component_module
  implicit none
  type finalizable_component
    final :: finalize
  end type
  subroutine finalize(this)
    type(finalizable_component) :: this
    print *,'subroutine finalize called'
  end subroutine
end module

module abstract_parent_module
  use finalizable_component_module
  implicit none
  type ,abstract :: abstract_parent
    type(finalizable_component) :: foo
  end type
end module

module child_module
  use abstract_parent_module
  implicit none
  type, extends(abstract_parent) :: child
  end type
  type(child) function new_child()
  end function
end module

program main
  use child_module
  implicit none
  type(child),allocatable :: infant

This is accomplished by adding a routine 'gfc_is_finalizable', which
checks if a derived type is 'finalizable' (as defined in the Fortran
standard). For such types, we need to generate a (non-polymorphic)
call to the finalizer, also for non-polymorphic variables (as in the
above test case).

There are still some issues with this:

(1) We currently generate a call like this:

            desc.4.dtype = 600;
   = (void * restrict) infant;
            __final_abstract_parent_module_Abstract_parent (&desc.4, 0);

i.e. we call the finalization wrapper of the abstract parent, but pass
a variable of type 'child' (which is wrong). To solve this, I think we
should also generate a wrapper for types like 'child', who just need
to finalize their parent component.
The alternative would be to directly call the parent finalizer (as we
do now), and pass the correct component, i.e. infant->abstract_parent.
However, this can become complicated for large extension chains, so
why not put this complexity into the wrapper?

(2) For the test case above, we generate exactly one finalization call
(automatic deallocation at the end of the program). But when changing
the declaration of 'infant' to

CLASS(child),allocatable :: infant

then we generate two calls. One of them seems to come from the _copy
routine. I'm not sure if this is correct. How many finalizer calls
should we have here? (I guess the answer should be the same for TYPE
and CLASS, right?)

(3) For the original test case in PR 37336, with

program main
  use child_module
  implicit none
  type(child) :: infant
  infant = new_child()

we still do not call the finalizer. And to be honest I am not
completely sure if we should. Is 'infant' supposed to be finalized
here (at the end of the main program)?


Attachment: final-2012-10-27.diff
Description: Binary data

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]