This is the mail archive of the fortran@gcc.gnu.org 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


Answers interspersed below:


On 10/27/12 6:09 AM, "Janus Weil" <janus@gcc.gnu.org> wrote:

>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
>  contains
>    final :: finalize
>  end type
>contains
>  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
>contains
>  type(child) function new_child()
>  end function
>end module
>
>program main
>  use child_module
>  implicit none
>  type(child),allocatable :: infant
>  allocate(infant,source=new_child())
>end
>
>
>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;
>            desc.4.data = (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?)

In case it helps, both the IBM and NAG compilers call the final subroutine
once in the above reduced test case regardless of whether the "infant"
declaration uses  "type" or "class".  The Intel compiler calls it once
when the declaration is "class".  Intel causes a runtime segfault when the
declaration is "type", but I'm pretty sure that's a known bug that has
been fixed in their latest release, which I don't currently have.  I'll
check with Intel.


>
>
>(3) For the original test case in PR 37336, with
>
>program main
>  use child_module
>  implicit none
>  type(child) :: infant
>  infant = new_child()
>end
>
>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)?

Karla and I have had extensive interactions with at least three other
compiler teams on this question.  Although I can't cite the relevant text
from the standard, each correspondence ended with the conclusion that the
infant must be finalized before the intrinsic assignment jcopies the
new_child() result into infant.  Of course, the final subroutine must also
be called on the new_child() result so that totals two invocations of the
final subroutine. I just verified that the NAG, IBM, and Intel compilers
each call the final subroutine twice for the above code.

>
>Cheers,
>Janus



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