Bug 37336

Summary: [F03] Finish derived-type finalization
Product: gcc Reporter: Daniel Kraft <domob>
Component: fortranAssignee: Tobias Burnus <burnus>
Status: NEW ---    
Severity: enhancement CC: andrew, burnus, damian, dfranke, gcc-bugs, janus, knmorri, sfilippone, slayoo, tkoenig, w6ws, wangmianzhi1
Priority: P3    
Version: unknown   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Bug Depends on: 55207, 55603, 59694, 64290, 65347, 58026, 58470, 59765    
Bug Blocks: 20585    
Attachments: Proposed patch implementing the main part

Description Daniel Kraft 2008-09-02 16:59:23 UTC
Derived-type finalization as defined in Fortran 2003 is at the moment partially implemented in gfortran.  FINAL bindings are parsed and stored/loaded in .mod module files, but finalizers are not yet executed and a not-yet-implemented error appears on using FINAL.
Comment 1 Daniel Kraft 2008-09-02 17:05:16 UTC
Created attachment 16196 [details]
Proposed patch implementing the main part

This is an experimental patch that implements the logic to create code finalizing a given entity.  Only with this patch, this is however never called; this is merely a preparation for a full implementation of derived-type finalization.  This patch was posted to the mailing lists as http://gcc.gnu.org/ml/fortran/2008-08/msg00042.html.

It is a split-off from an experimental full finalization patch posted as http://gcc.gnu.org/ml/fortran/2008-06/msg00254.html and follow-up discussion.
Comment 2 Daniel Kraft 2008-09-02 17:08:21 UTC
For the needed parts to actually call finalizers building upon the attached patch from comment #1, some means for temporary-creation before trans are needed to handle things like:

x = foo (x)

or

foo (bar ())

Some ideas were posted to the mailing list as http://gcc.gnu.org/ml/fortran/2008-08/msg00026.html.
Comment 3 Tobias Burnus 2010-06-23 14:13:59 UTC
[Cf. also Corrigenda 1 to 5 (informal collection of these 5 documents) ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1823.pdf (F2008 should incorporate those changes)]  Current (on-going) interpretation requests:

http://j3-fortran.org/doc/meeting/192/10-158.txt
http://j3-fortran.org/doc/meeting/192/10-159.txt
http://j3-fortran.org/doc/meeting/192/10-160.txt
http://j3-fortran.org/doc/meeting/192/10-161.txt

 * * * 

Last patch was http://gcc.gnu.org/ml/fortran/2008-11/msg00229.html
Comment 4 Tobias Burnus 2010-06-23 14:21:46 UTC
Add another J3 meeting #192 link, which is only a discussion item, but give some idea: http://j3-fortran.org/doc/meeting/192/10-164.txt
Comment 5 Tobias Burnus 2010-10-26 07:45:53 UTC
Related issue: When a polymorphic types has to be finallized, e.g. when it leaves the scope, the allocatable components of the effective type have to be freed - not only those of the declared type. Cf. PR 46174
Comment 6 Damian Rouson 2010-12-02 04:35:39 UTC
The test case below is a test of finalization of a concrete component of an abstract type when a type that extends the abstract type goes out of scope.  I'm working on determining how many times the final subroutine should be called -- certainly at least once to finalize the new_child function result when it goes out of scope after the assignment. 

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) :: infant
  infant = new_child()
end
Comment 7 Daniel Franke 2010-12-27 02:04:07 UTC
I had the vague impression that FINAL was already completed, so I gave it a try ... 

polytest.f90:28.22:

  SUBROUTINE free(this)
                      1
Error: Argument of FINAL procedure at (1) must be of type 'abstract_weight'

for
  SUBROUTINE free(this)
    CLASS(abstract_weight), INTENT(inout) :: this
    ! ...
  END SUBROUTINE

Placing the error marker at CLASS() and rewording to "must be of 'TYPE(abstract_weight)'" might ease some confusion. It took me a while to figure out what's wrong ^^

However, any plans to get this completed in the foreseeable future?
Comment 8 Walter Spector 2012-03-15 17:24:59 UTC
Should this bug report number be added to the F2003 meta bug?  (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20585)
Comment 9 Thomas Koenig 2012-03-18 15:22:17 UTC
(In reply to comment #8)
> Should this bug report number be added to the F2003 meta bug? 
> (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20585)

You're right, added.
Comment 10 Tobias Burnus 2012-05-07 10:09:52 UTC
Regarding FINAL but also normal deallocation - including polymorphic deallocation: Variables with the SAVE attribute shouldn't be automatically deallocated. That includes variables of the main program which are implicitly SAVE!

Currently, gfortran deallocates them automatically, which is nice for "valgrind" results - and not detectable by the program.

However, with FINAL - but also for allocatable coarrays (except -fcoarray=single) - one cannot do it. Coarrays might be still accessed from other images while FINAL shouldn't be called - thus a simple 'print *, "gotcha"' in FINAL would be able to detect this.

Note: A normal freeing for noncoarrays, including polymorphic freeing, would be still possible if one simply skips all FINAL calls. At least I do not see how that should be detectable from within the program.
Comment 11 Tobias Burnus 2012-09-03 06:36:05 UTC
Author: burnus
Date: Mon Sep  3 06:35:59 2012
New Revision: 190869

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190869
Log:
2012-09-03  Alessandro Fanfarillo  <fanfarillo.gcc@gmail.com>
            Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * gfortran.h (symbol_attribute): Add artificial.
        * module.c (mio_symbol_attribute): Handle attr.artificial
        * class.c (gfc_build_class_symbol): Defer creation of the vtab
        if the DT has finalizers, mark generated symbols as
        attr.artificial.
        (has_finalizer_component, finalize_component,
        finalization_scalarizer, generate_finalization_wrapper):
        New static functions.
        (gfc_find_derived_vtab): Add _final component and call
        generate_finalization_wrapper.
        * dump-parse-tree.c (show_f2k_derived): Use resolved
        proc_tree->n.sym rather than unresolved proc_sym.
        (show_attr): Handle attr.artificial.
        * resolve.c (gfc_resolve_finalizers): Ensure that the vtab
        * exists.
        (resolve_fl_derived): Resolve finalizers before
        generating the vtab.
        (resolve_symbol): Also allow assumed-rank arrays with CONTIGUOUS;
        skip artificial symbols.
        (resolve_fl_derived0): Skip artificial symbols.

2012-09-03  Tobias Burnus  <burnus@net-b.de>

        PR fortran/51632
        * gfortran.dg/coarray_class_1.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/coarray_class_1.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/dump-parse-tree.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 Tobias Burnus 2012-09-22 17:08:08 UTC
Incomplete but mostly finished draft patches:
https://userpage.physik.fu-berlin.de/~tburnus/final/
Comment 13 janus 2012-10-26 16:47:08 UTC
Latest patch at: http://gcc.gnu.org/ml/fortran/2012-10/msg00126.html

This patch compiles the test case in comment 6 without errors, but the finalizer is not called.

However, when changing the main program to ...

program main
  use child_module
  implicit none
  class(child),allocatable :: infant
  allocate(infant,source=new_child())
end

... the finalizer is called twice: Once at the end of the main program, and once through the _copy procedure (which is invoked by the ALLOCATE statement), I think. Not sure if this is the expected behavior.

If the "class(child)" here is changed to "type(child)", no finalization is done (and in fact not even a finalization routine is generated for the type 'child').
But certainly it should, just as for the original test case in comment 6.
Comment 14 Tobias Burnus 2012-11-27 20:04:21 UTC
(In reply to comment #13)
>   class(child),allocatable :: infant
>   allocate(infant,source=new_child())

> ... the finalizer is called twice: Once at the end of the main program, and
> once through the _copy procedure (which is invoked by the ALLOCATE statement),
> I think. Not sure if this is the expected behavior.

The invocation through the _copy wrapper is a bug for ALLOCATE. However, it's fine for "a = b" which invoke _copy. I believe _copy should use "intent(inout) dst" instead of "intent(out)" dest – and if needed (e.g. intrinsic assignment), _final should be called directly. Then one can also replace "calloc" and "memset '\0'" by a simple "malloc". (Caveat: One should check that coarray components are properly handled; possibly, _copy also needs a "coarray" argument as _final has.)

 * * *

Current FINAL-wrapper patch (submitted) - it is still preparatory and doesn't call finalization subroutines:
   http://gcc.gnu.org/ml/fortran/2012-11/msg00086.html

See also draft patches at https://userpage.physik.fu-berlin.de/~tburnus/final/
and http://gcc.gnu.org/ml/fortran/2012-11/msg00009.html
Comment 15 Tobias Burnus 2012-12-03 08:54:26 UTC
Author: burnus
Date: Mon Dec  3 08:54:18 2012
New Revision: 194075

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194075
Log:
2012-11-03  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * class.c (finalizer_insert_packed_call): New static function.
        (finalize_component, generate_finalization_wrapper):
        Fix coarray handling and packing.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
Comment 16 janus 2012-12-03 09:00:14 UTC
(In reply to comment #15)
> Author: burnus
> Date: Mon Dec  3 08:54:18 2012
> New Revision: 194075
> 
> URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194075
> Log:
> 2012-11-03  Tobias Burnus  <burnus@net-b.de>

Nitpicking: Wrong date! (It's December already ;)
Comment 17 Tobias Burnus 2012-12-03 21:13:50 UTC
Author: burnus
Date: Mon Dec  3 21:13:42 2012
New Revision: 194104

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194104
Log:
2012-12-03  Tobias Burnus  <burnus@net-b.de>
            Janus Weil  <janus@gcc.gnu.org>

        PR fortran/37336
        * class.c (gfc_is_finalizable): New function.
        * gfortran.h (gfc_is_finalizable): Its prototype.
        * module.c (mio_component): Read initializer for vtype's _final.
        * resolve.c (resolve_fl_derived0): Call gfc_is_finalizable.
        * trans-expr.c (gfc_vtable_final_get): New function.
        (conv_parent_component_references): Fix comment.
        (gfc_conv_variable): Fix for scalar coarray components.
        * trans-intrinsic.c (conv_intrinsic_move_alloc): For BT_CLASS,
        pass the BT_CLASS type and not the declared type to
        gfc_deallocate_scalar_with_status.
        * trans.h (gfc_vtable_final_get): New prototype.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-intrinsic.c
    trunk/gcc/fortran/trans.h
Comment 18 janus 2012-12-05 08:54:01 UTC
Adding two auto-dealloc bugs, which need to be fixed in order to get correct finalization calls.
Comment 19 Tobias Burnus 2013-05-28 18:30:53 UTC
Author: burnus
Date: Tue May 28 18:30:03 2013
New Revision: 199388

URL: http://gcc.gnu.org/viewcvs?rev=199388&root=gcc&view=rev
Log:
2013-05-28  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * resolve.c (gfc_resolve_finalizers): Remove not implemented
        * error.

2013-05-28  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * gfortran.dg/finalize_11.f90: New.
        * gfortran.dg/finalize_4.f03: Remove dg-error.
        * gfortran.dg/finalize_5.f03: Ditto.
        * gfortran.dg/finalize_6.f03: Ditto.
        * gfortran.dg/finalize_7.f03: Ditto.


Added:
    trunk/gcc/testsuite/gfortran.dg/finalize_11.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/finalize_4.f03
    trunk/gcc/testsuite/gfortran.dg/finalize_5.f03
    trunk/gcc/testsuite/gfortran.dg/finalize_6.f90
    trunk/gcc/testsuite/gfortran.dg/finalize_7.f03
Comment 20 Tobias Burnus 2013-05-28 18:33:07 UTC
The patch in comment 19 enables the FINAL parsing.

Note: No actual finalization is done, yet. However, the first calls to the finalization subroutines will be added soon.
Comment 21 Tobias Burnus 2013-05-29 13:23:22 UTC
Author: burnus
Date: Wed May 29 13:15:16 2013
New Revision: 199409

URL: http://gcc.gnu.org/viewcvs?rev=199409&root=gcc&view=rev
Log:
2013-05-28  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * class.c (finalize_component): Fix coarray array refs.
        (generate_finalization_wrapper): Only gfc_convert_type_warn
        when the kind value is different.
        (gfc_find_intrinsic_vtab): _copy's dst is now intent(inout).
        (gfc_find_derived_vtab): Ditto. Enable finalization-wrapper
        generation.
        * module.c (MOD_VERSION): Bump.
        (gfc_dump_module, gfc_use_module): Remove empty line in .mod.
        * trans-array.c (gfc_conv_descriptor_token): Accept
        * nonrestricted
        void pointer.
        (gfc_array_allocate, structure_alloc_comps): Don't nullify for
        BT_CLASS allocations.
        * trans-stmt.c (gfc_trans_allocate): Ditto.

2013-05-28  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * gfortran.dg/auto_dealloc_2.f90: Update _free count in the
        * dump.
        * gfortran.dg/class_19.f03: Ditto.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
    trunk/gcc/testsuite/gfortran.dg/class_19.f03
Comment 22 Tobias Burnus 2013-05-29 13:26:40 UTC
The patch in comment 21 enables the generation of the finalization wrapper, which is at the heart of finalization.

Note: No actual finalization is done, yet. Still missing are calls to the finalization wrapper. That will be a lengthier process. The first patch of that series is available at http://gcc.gnu.org/ml/fortran/2013-05/msg00107.html
Comment 23 Tobias Burnus 2013-06-04 10:21:39 UTC
Author: burnus
Date: Tue Jun  4 10:20:32 2013
New Revision: 199643

URL: http://gcc.gnu.org/viewcvs?rev=199643&root=gcc&view=rev
Log:
2013-06-03  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * trans.h (gfc_build_final_call): Remove prototype.
        (gfc_add_finalizer_call): Add prototype.
        * trans-array.c (gfc_trans_dealloc_allocated): Support
        * finalization.
        (structure_alloc_comps): Update caller.
        (gfc_trans_deferred_array): Call finalizer.
        * trans-array.h (gfc_trans_dealloc_allocated): Update prototype.
        * trans-decl.c (gfc_trans_deferred_vars): Don't
        * deallocate/finalize
        variables of the main program.
        * trans-expr.c (gfc_conv_procedure_call): Support finalization.
        * trans-openmp.c (gfc_omp_clause_dtor,
        gfc_trans_omp_array_reduction): Update calls.
        * trans-stmt.c (gfc_trans_deallocate): Avoid double deallocation
        of alloc components.
        * trans.c (gfc_add_finalizer_call): New function.
        (gfc_deallocate_with_status,
        gfc_deallocate_scalar_with_status): Call it
        (gfc_build_final_call): Fix handling of scalar coarrays,
        move up in the file and make static.

2013-06-03  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * gfortran.dg/finalize_12.f90: New.
        * gfortran.dg/alloc_comp_basics_1.f90: Add BLOCK for
        end of scope finalization.
        * gfortran.dg/alloc_comp_constructor_1.f90: Ditto.
        * gfortran.dg/allocatable_scalar_9.f90: Ditto.
        * gfortran.dg/auto_dealloc_2.f90: Ditto.
        * gfortran.dg/class_19.f03: Ditto.
        * gfortran.dg/coarray_lib_alloc_1.f90: Ditto.
        * gfortran.dg/coarray_lib_alloc_2.f90: Ditto.
        * gfortran.dg/extends_14.f03: Ditto.
        * gfortran.dg/move_alloc_4.f90: Ditto.
        * gfortran.dg/typebound_proc_27.f03: Ditto.


Added:
    trunk/gcc/testsuite/gfortran.dg/finalize_12.f90
    trunk/gcc/testsuite/gfortran.dg/finalize_13.f90
    trunk/gcc/testsuite/gfortran.dg/finalize_14.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-array.h
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-openmp.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_basics_1.f90
    trunk/gcc/testsuite/gfortran.dg/alloc_comp_constructor_1.f90
    trunk/gcc/testsuite/gfortran.dg/allocatable_scalar_9.f90
    trunk/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
    trunk/gcc/testsuite/gfortran.dg/class_19.f03
    trunk/gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f90
    trunk/gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f90
    trunk/gcc/testsuite/gfortran.dg/extends_14.f03
    trunk/gcc/testsuite/gfortran.dg/move_alloc_4.f90
    trunk/gcc/testsuite/gfortran.dg/typebound_proc_27.f03
Comment 24 Tobias Burnus 2013-06-04 10:27:00 UTC
The patch in comment 23 adds finalization support for allocatables (end of scope, intent(out), DEALLOCATE, MOVE_ALLOC).

Thus, on the trunk (GCC 4.9), finalization is now finally supported :-)

Note: There are additional cases for which finalization has to be done, e.g. for intent(out) of nonallocatable (patch: http://gcc.gnu.org/ml/fortran/2013-05/msg00135.html), end-of-scope of nonallocatables, intrinsic assignment, function results + array/structure constructors - after there use in expressions.
Comment 25 Tobias Burnus 2013-06-08 12:28:06 UTC
Author: burnus
Date: Sat Jun  8 12:26:40 2013
New Revision: 199851

URL: http://gcc.gnu.org/viewcvs?rev=199851&root=gcc&view=rev
Log:
2013-06-08  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * trans-decl.c (init_intent_out_dt): Call finalizer
        when approriate.

2013-06-08  Tobias Burnus  <burnus@net-b.de>

        PR fortran/37336
        * gfortran.dg/finalize_10.f90: New.
        * gfortran.dg/auto_dealloc_2.f90: Update tree-dump.
        * gfortran.dg/finalize_15.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/finalize_10.f90
    trunk/gcc/testsuite/gfortran.dg/finalize_15.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
Comment 26 Tobias Burnus 2013-06-21 21:53:29 UTC
Author: burnus
Date: Fri Jun 21 21:51:41 2013
New Revision: 200321

URL: http://gcc.gnu.org/viewcvs?rev=200321&root=gcc&view=rev
Log:
2013-06-21  Tobias Burnus  <burnus@net-b.de>

        * trans-array.c (gfc_trans_deferred_array): Call the
        finalizer for nonallocatable local variables.
        * trans-decl.c (gfc_get_symbol_decl): Add local
        finalizable vars to the deferred list.
        (gfc_trans_deferred_vars): Call gfc_trans_deferred_array
        for those.

2013-06-21  Tobias Burnus  <burnus@net-b.de>

        * gfortran.dg/finalize_17.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/finalize_17.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog
Comment 27 janus 2013-12-20 22:45:13 UTC
From http://gcc.gnu.org/ml/fortran/2013-12/msg00104.html ...

Currently missing are:

a) Finalization of the LHS during intrinsic assignment:
b) Finalization of functions results after their use
c) Finalization of structure/array constructors after their use.
Comment 28 janus 2014-12-15 11:50:03 UTC
(In reply to janus from comment #27)
> Currently missing are:
> 
> a) Finalization of the LHS during intrinsic assignment:

aka PR 64290
Comment 29 sourcery 2015-02-15 16:57:54 UTC
Good news. 

Hopefully you saw the email about the tutorial proposals. Strangely ISC asks for "1/2 page" CVs, which I interpret as half-page CVs (Karla was hoping they meant 1-2 page, but I think we should err on the safer side. You'll probably want to checkout the reduced version I constructed for you.  


D

D

Sent from my iPhone

> On Feb 15, 2015, at 8:03 AM, dominiq at lps dot ens.fr <gcc-bugzilla@gcc.gnu.org> wrote:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37336
> Bug 37336 depends on bug 59765, which changed state.
> 
> Bug 59765 Summary: [4.9/5 Regression] [OOP] ICE on valid with finalizable array components
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59765
> 
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>             Status|NEW                         |RESOLVED
>         Resolution|---                         |FIXED
> 
> -- 
> You are receiving this mail because:
> You are on the CC list for the bug.
>