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.
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.
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.
[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
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
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
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
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?
Should this bug report number be added to the F2003 meta bug? (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20585)
(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.
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.
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
Incomplete but mostly finished draft patches: https://userpage.physik.fu-berlin.de/~tburnus/final/
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.
(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
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
(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 ;)
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
Adding two auto-dealloc bugs, which need to be fixed in order to get correct finalization calls.
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
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.
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
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
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
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.
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
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
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.
(In reply to janus from comment #27) > Currently missing are: > > a) Finalization of the LHS during intrinsic assignment: aka PR 64290
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. >
Are there any plans on finishing the finalization implementation? To me it looks that the missing cases are the last open issues (besides some minor known bug) to claim complete F2003 implementation.
The master branch has been updated by Bernhard Reutner-Fischer <aldot@gcc.gnu.org>: https://gcc.gnu.org/g:8875a92d31329ae52b734683784c4b054839a661 commit r12-5073-g8875a92d31329ae52b734683784c4b054839a661 Author: Bernhard Reutner-Fischer <aldot@gcc.gnu.org> Date: Fri Oct 12 23:57:21 2018 +0200 Fortran: Fix memory leak in finalization wrappers [PR68800] If a finalization is not required we created a namespace containing formal arguments for an internal interface definition but never used any of these. So the whole sub_ns namespace was not wired up to the program and consequently was never freed. The fix is to simply not generate any finalization wrappers if we know that it will be unused. Note that this reverts back to the original r190869 (8a96d64282ac534cb597f446f02ac5d0b13249cc) handling for this case by reverting this specific part of r194075 (f1ee56b4be7cc3892e6ccc75d73033c129098e87) for PR fortran/37336. valgrind summary for e.g. gfortran.dg/abstract_type_3.f03 and gfortran.dg/abstract_type_4.f03 where ".orig" is pristine trunk and ".mine" contains this fix: at3.orig.vg:LEAK SUMMARY: at3.orig.vg- definitely lost: 8,460 bytes in 11 blocks at3.orig.vg- indirectly lost: 13,288 bytes in 55 blocks at3.orig.vg- possibly lost: 0 bytes in 0 blocks at3.orig.vg- still reachable: 572,278 bytes in 2,142 blocks at3.orig.vg- suppressed: 0 bytes in 0 blocks at3.orig.vg- at3.orig.vg-Use --track-origins=yes to see where uninitialised values come from at3.orig.vg-ERROR SUMMARY: 38 errors from 33 contexts (suppressed: 0 from 0) -- at3.mine.vg:LEAK SUMMARY: at3.mine.vg- definitely lost: 344 bytes in 1 blocks at3.mine.vg- indirectly lost: 7,192 bytes in 18 blocks at3.mine.vg- possibly lost: 0 bytes in 0 blocks at3.mine.vg- still reachable: 572,278 bytes in 2,142 blocks at3.mine.vg- suppressed: 0 bytes in 0 blocks at3.mine.vg- at3.mine.vg-ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) at3.mine.vg-ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) at4.orig.vg:LEAK SUMMARY: at4.orig.vg- definitely lost: 13,751 bytes in 12 blocks at4.orig.vg- indirectly lost: 11,976 bytes in 60 blocks at4.orig.vg- possibly lost: 0 bytes in 0 blocks at4.orig.vg- still reachable: 572,278 bytes in 2,142 blocks at4.orig.vg- suppressed: 0 bytes in 0 blocks at4.orig.vg- at4.orig.vg-Use --track-origins=yes to see where uninitialised values come from at4.orig.vg-ERROR SUMMARY: 18 errors from 16 contexts (suppressed: 0 from 0) -- at4.mine.vg:LEAK SUMMARY: at4.mine.vg- definitely lost: 3,008 bytes in 3 blocks at4.mine.vg- indirectly lost: 4,056 bytes in 11 blocks at4.mine.vg- possibly lost: 0 bytes in 0 blocks at4.mine.vg- still reachable: 572,278 bytes in 2,142 blocks at4.mine.vg- suppressed: 0 bytes in 0 blocks at4.mine.vg- at4.mine.vg-ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) at4.mine.vg-ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) gcc/fortran/ChangeLog: 2018-10-12 Bernhard Reutner-Fischer <aldot@gcc.gnu.org> PR fortran/68800 * class.c (generate_finalization_wrapper): Do not leak finalization wrappers if they will not be used. * expr.c (gfc_free_actual_arglist): Formatting fix. * gfortran.h (gfc_free_symbol): Pass argument by reference. (gfc_release_symbol): Likewise. (gfc_free_namespace): Likewise. * symbol.c (gfc_release_symbol): Adjust acordingly. (free_components): Set procedure pointer components of derived types to NULL after freeing. (free_tb_tree): Likewise. (gfc_free_symbol): Set sym to NULL after freeing. (gfc_free_namespace): Set namespace to NULL after freeing.