[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 Paul Thomas changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #27 from Paul Thomas --- (In reply to zed.three from comment #26) > Thank you for looking at the finalisation stuff, Paul, it's really > appreciated! > > It wasn't clear to me from the patch notes if you expect the following to be > fixed: > > subroutine assign_a_type(lhs, rhs) > class(a_type_t), intent(inout) :: lhs > class(a_type_t), intent(in):: rhs > lhs%x = rhs%x > end subroutine assign_a_type > > or > > class(a_type_t), allocatable :: c > c = add_a_type(a, b) > > These still generate memory leaks (detected using -fsanitize=address) > > I'm using trunk (r267184, git bf96f3) > > I've been trying to dig into the code myself, mostly as a learning exercise. > Am I right in thinking that gfc_conv_procedure_call handles the whole > statement? i.e. that finalisation both of the lhs and function result are > (or should be) done here? I am unable to reproduce the memory leaks that you mention, either with -fsanitize=address or valgrind. The statement is handled by gfc_conv_procedure_call as you say. I am closing this PR since it is fixed on trunk. Paul
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 zed.three at gmail dot com changed: What|Removed |Added CC||zed.three at gmail dot com --- Comment #26 from zed.three at gmail dot com --- Thank you for looking at the finalisation stuff, Paul, it's really appreciated! It wasn't clear to me from the patch notes if you expect the following to be fixed: subroutine assign_a_type(lhs, rhs) class(a_type_t), intent(inout) :: lhs class(a_type_t), intent(in):: rhs lhs%x = rhs%x end subroutine assign_a_type or class(a_type_t), allocatable :: c c = add_a_type(a, b) These still generate memory leaks (detected using -fsanitize=address) I'm using trunk (r267184, git bf96f3) I've been trying to dig into the code myself, mostly as a learning exercise. Am I right in thinking that gfc_conv_procedure_call handles the whole statement? i.e. that finalisation both of the lhs and function result are (or should be) done here?
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 Martin Liška changed: What|Removed |Added CC||marxin at gcc dot gnu.org --- Comment #25 from Martin Liška --- Paul: Can the bug be marked as resolved?
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #24 from Paul Thomas --- Author: pault Date: Tue Aug 28 11:35:52 2018 New Revision: 263916 URL: https://gcc.gnu.org/viewcvs?rev=263916=gcc=rev Log: 2017-08-28 Paul Thomas PR fortran/80477 * trans-expr.c (gfc_conv_procedure_call): Allocatable class scalar results being passed to a derived type formal argument are finalized if possible. Otherwise, rely on existing code for deallocation. Make the deallocation of allocatable result components conditional on finalization not taking place. Make the freeing of data components after finalization conditional on the data being NULL. (gfc_trans_arrayfunc_assign): Change the gcc_assert to a condition to return NULL_TREE. (gfc_trans_assignment_1): If the assignment is class to class and the rhs expression must be finalized but the assignment is not marked as a polymorphic assignment, use the vptr copy function instead of gfc_trans_scalar_assign. PR fortran/86481 * trans-expr.c (gfc_conv_expr_reference): Do not add the post block to the pre block if the expression is to be finalized. * trans-stmt.c (gfc_trans_allocate): If the expr3 must be finalized, load the post block into a finalization block and add it right at the end of the allocation block. 2017-08-28 Paul Thomas PR fortran/80477 * gfortran.dg/class_result_7.f90: New test. * gfortran.dg/class_result_8.f90: New test. * gfortran.dg/class_result_9.f90: New test. PR fortran/86481 * gfortran.dg/allocate_with_source_25.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/allocate_with_source_25.f90 trunk/gcc/testsuite/gfortran.dg/class_result_7.f90 trunk/gcc/testsuite/gfortran.dg/class_result_8.f90 trunk/gcc/testsuite/gfortran.dg/class_result_9.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-expr.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/testsuite/ChangeLog
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 Paul Thomas changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |pault at gcc dot gnu.org --- Comment #23 from Paul Thomas --- Created attachment 44457 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44457=edit A fix for the PR I have just posted the attached fix to the list. Should it be backported - it is very innocuous? Paul
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 Jakub Jelinek changed: What|Removed |Added Target Milestone|8.2 |8.3 --- Comment #22 from Jakub Jelinek --- GCC 8.2 has been released.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 Jakub Jelinek changed: What|Removed |Added Target Milestone|8.0 |8.2 --- Comment #21 from Jakub Jelinek --- GCC 8.1 has been released.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #20 from janus at gcc dot gnu.org --- (In reply to janus from comment #19) > And IIRC we even use the finalization > wrapper for deallocating polymorphic variables in other cases (even if they > have no actual FINAL procedures). In fact the finalization wrapper itself does not take care of deallocating the variable (since finalization also applies to non-allocatable variables), but it does deallocate any allocatable components (if existent). Plus: For any polymorphic variable, we need to check at *runtime* whether finalization is necessary, since an extended type may have finalizers, even if the base class does not. The typical code that is generated for the deallocation of a polymorphic variable 'c' looks like this: if (c._data != 0B) { if (c._vptr->_final != 0B) { { struct array0_t desc.0; desc.0.dtype = 40; desc.0.data = (void * restrict) c._data; c._vptr->_final (, c._vptr->_size, 0); } } __builtin_free ((void *) c._data); }
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 janus at gcc dot gnu.org changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=65347 --- Comment #19 from janus at gcc dot gnu.org --- I think this PR is very much related to PR 65347 ("Final subroutine not called for function result") ... Deallocation and finalization of function results are very similar. Both require a temporary to be generated. And IIRC we even use the finalization wrapper for deallocating polymorphic variables in other cases (even if they have no actual FINAL procedures). Such an approach would fix both PRs in one go.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #18 from janus at gcc dot gnu.org --- (In reply to paul.richard.tho...@gmail.com from comment #16) > The attached does what you want to the testcase. For CLASS objects, it > is the data that has to be copied to a variable, that data freed and > the _data field pointed to the variable. There are about 70 failing > tests. I actually see 52 testsuite failures with your patch, namely in the files: FAIL: gfortran.dg/alloc_comp_class_4.f03 -O0 execution test FAIL: gfortran.dg/class_result_1.f03 -O1 (internal compiler error) FAIL: gfortran.dg/class_to_type_4.f90 -O0 execution test FAIL: gfortran.dg/init_flag_15.f03 -O0 execution test FAIL: gfortran.dg/submodule_6.f08 -O0 execution test FAIL: gfortran.dg/typebound_operator_8.f03 -O0 execution test It seems the patch currently fails at runtime for cases where the class variable has allocatable components, like this reduction of alloc_comp_class_4.f03: module test_pr58586_mod implicit none type :: c integer, allocatable :: a end type contains subroutine add_class_c (d) class(c), value :: d end subroutine class(c) function c_init2() allocatable :: c_init2 end function end module test_pr58586_mod program test_pr58586 use test_pr58586_mod call add_class_c(c_init2()) end program The dump is: test_pr58586 () { { struct __class_test_pr58586_mod_C_a D.3598; struct c D.3599; D.3598 = c_init2 (); D.3599 = *D.3598._data; __builtin_free ((void *) D.3598._data); D.3598._data = 0B; D.3598._data = add_class_c (D.3598); if (D.3598._data != 0B) { if (D.3598._data->a != 0B) { __builtin_free ((void *) D.3598._data->a); D.3598._data->a = 0B; } __builtin_free ((void *) D.3598._data); D.3598._data = 0B; } } }
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #17 from janus at gcc dot gnu.org --- Hi Paul, (In reply to paul.richard.tho...@gmail.com from comment #16) > The attached does what you want to the testcase. For CLASS objects, it > is the data that has to be copied to a variable, that data freed and > the _data field pointed to the variable. There are about 70 failing > tests. I can continue debugging tonight or leave it to you. thanks a lot for the patch. I also managed to cook up a working patch this afternoon, which I think is very similar to yours, however it even has 211 failures in the testsuite :( I will try sifting out these regressions, unless you beat me to it ...
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #16 from paul.richard.thomas at gmail dot com --- Hi Janus, The attached does what you want to the testcase. For CLASS objects, it is the data that has to be copied to a variable, that data freed and the _data field pointed to the variable. There are about 70 failing tests. I can continue debugging tonight or leave it to you. Best regards Paul On 23 April 2017 at 12:02, janus at gcc dot gnu.orgwrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 > > janus at gcc dot gnu.org changed: > >What|Removed |Added > > CC||pault at gcc dot gnu.org > > --- Comment #9 from janus at gcc dot gnu.org --- > Anyway, getting back to the discussion of the actual bug ... > > (In reply to janus from comment #4) >> When changing the function result from CLASS to TYPE, this deallocation >> seems to be done properly (valgrind shows no leak), and the dump looks like >> this: >> >> [...] > > Based on this observation, I cooked up a draft patch that tries to modify the > code which does the freeing for TYPEs and make it work for CLASSes: > > > Index: gcc/fortran/trans-expr.c > === > --- gcc/fortran/trans-expr.c(revision 247083) > +++ gcc/fortran/trans-expr.c(working copy) > @@ -6131,15 +6131,26 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * >/* Allocatable scalar function results must be freed and nullified > after use. This necessitates the creation of a temporary to > hold the result to prevent duplicate calls. */ > - if (!byref && sym->ts.type != BT_CHARACTER > - && sym->attr.allocatable && !sym->attr.dimension) > + if (!byref && sym->ts.type != BT_CHARACTER) > { > - tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); > - gfc_add_modify (>pre, tmp, se->expr); > - se->expr = tmp; > - tmp = gfc_call_free (tmp); > - gfc_add_expr_to_block (, tmp); > - gfc_add_modify (, se->expr, build_int_cst (TREE_TYPE (se->expr), > 0)); > + if (sym->attr.allocatable && !sym->attr.dimension) > + { > + tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); > + gfc_add_modify (>pre, tmp, se->expr); > + se->expr = tmp; > + gfc_add_expr_to_block (, gfc_call_free (tmp)); > + gfc_add_modify (, tmp, build_int_cst (TREE_TYPE (tmp), 0)); > + } > + else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.allocatable > + && !CLASS_DATA (sym)->attr.dimension) > + { > + tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); > + gfc_add_modify (>pre, tmp, se->expr); > + se->expr = tmp; > + tmp = gfc_class_data_get (tmp); > + gfc_add_expr_to_block (, gfc_call_free (tmp)); > + gfc_add_modify (, tmp, build_int_cst (TREE_TYPE (tmp), 0)); > + } > } > >/* If we have a pointer function, but we don't want a pointer, e.g. > > > Unfortunately it does not work, because it only creates a copy of the class > container, but frees up the class data too early: > > > polymorphic_operators_memory_leaks () > { > static struct a_type_t a = {.x=1.0e+0}; > static struct a_type_t b = {.x=2.0e+0}; > > { > struct __class_a_type_m_A_type_t_a D.3528; > struct __class_a_type_m_A_type_t_a D.3529; > > D.3528 = add_a_type (, ); > D.3529 = D.3528; > __builtin_free ((void *) D.3528._data); > D.3528._data = 0B; > assign_a_type (, D.3529._data); > } > } > > > I guess I could use some help here (I always tend to get a bit lost in the > trans-stage). Paul, do you by chance have any idea how to handle this > properly? > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #15 from Stefano Zaghi --- Dear all, I add that the workaround (inserting an allocatable inside the type being a result of polymorphic function) if used into a real code (https://github.com/szaghi/FORESEER) does not solve the memory leak and generates Error in `./exe/foreseer_test_shock_tube': free(): invalid pointer: 0x7f04e4f80b00 I have not yet minimized this last example. I do not know if this is of some help. My best regards.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #14 from janus at gcc dot gnu.org --- (In reply to paul.richard.tho...@gmail.com from comment #11) > I'll take a look tonight. I believe, without the source in front of me, that > > s/gfc_add_expr_to_block (, gfc_call_free > (tmp));/gfc_add_expr_to_block (>post, gfc_call_free (tmp)); Thanks for the suggestion, Paul. I just tried it, but unfortunately it makes exactly zero difference, probably because gfc_conv_procedure_call has at the very end: gfc_add_block_to_block (>post, );
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #13 from Stefano Zaghi --- Dear all, I have done further test about Vipul's workaround, you can find my complete report here https://github.com/szaghi/leaks_hunter#results Essentially, my current conclusion is that the workaround does not work always. In particular the "simple inheritance leaker" test shows that the leak is still generated no matter the workaround is used. In this last case, I think that issues could be placed into the "child_t" finalizer: you can find the generated code here https://github.com/szaghi/leaks_hunter#note I hope this can help for your patch. My best regards.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #12 from Stefano Zaghi --- Created attachment 41267 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41267=edit simple inheritance leaker
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #11 from paul.richard.thomas at gmail dot com --- Hi Janus, I'll take a look tonight. I believe, without the source in front of me, that s/gfc_add_expr_to_block (, gfc_call_free (tmp));/gfc_add_expr_to_block (>post, gfc_call_free (tmp)); Cheers Paul On 23 April 2017 at 12:02, janus at gcc dot gnu.orgwrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 > > janus at gcc dot gnu.org changed: > >What|Removed |Added > > CC||pault at gcc dot gnu.org > > --- Comment #9 from janus at gcc dot gnu.org --- > Anyway, getting back to the discussion of the actual bug ... > > (In reply to janus from comment #4) >> When changing the function result from CLASS to TYPE, this deallocation >> seems to be done properly (valgrind shows no leak), and the dump looks like >> this: >> >> [...] > > Based on this observation, I cooked up a draft patch that tries to modify the > code which does the freeing for TYPEs and make it work for CLASSes: > > > Index: gcc/fortran/trans-expr.c > === > --- gcc/fortran/trans-expr.c(revision 247083) > +++ gcc/fortran/trans-expr.c(working copy) > @@ -6131,15 +6131,26 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * >/* Allocatable scalar function results must be freed and nullified > after use. This necessitates the creation of a temporary to > hold the result to prevent duplicate calls. */ > - if (!byref && sym->ts.type != BT_CHARACTER > - && sym->attr.allocatable && !sym->attr.dimension) > + if (!byref && sym->ts.type != BT_CHARACTER) > { > - tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); > - gfc_add_modify (>pre, tmp, se->expr); > - se->expr = tmp; > - tmp = gfc_call_free (tmp); > - gfc_add_expr_to_block (, tmp); > - gfc_add_modify (, se->expr, build_int_cst (TREE_TYPE (se->expr), > 0)); > + if (sym->attr.allocatable && !sym->attr.dimension) > + { > + tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); > + gfc_add_modify (>pre, tmp, se->expr); > + se->expr = tmp; > + gfc_add_expr_to_block (, gfc_call_free (tmp)); > + gfc_add_modify (, tmp, build_int_cst (TREE_TYPE (tmp), 0)); > + } > + else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.allocatable > + && !CLASS_DATA (sym)->attr.dimension) > + { > + tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); > + gfc_add_modify (>pre, tmp, se->expr); > + se->expr = tmp; > + tmp = gfc_class_data_get (tmp); > + gfc_add_expr_to_block (, gfc_call_free (tmp)); > + gfc_add_modify (, tmp, build_int_cst (TREE_TYPE (tmp), 0)); > + } > } > >/* If we have a pointer function, but we don't want a pointer, e.g. > > > Unfortunately it does not work, because it only creates a copy of the class > container, but frees up the class data too early: > > > polymorphic_operators_memory_leaks () > { > static struct a_type_t a = {.x=1.0e+0}; > static struct a_type_t b = {.x=2.0e+0}; > > { > struct __class_a_type_m_A_type_t_a D.3528; > struct __class_a_type_m_A_type_t_a D.3529; > > D.3528 = add_a_type (, ); > D.3529 = D.3528; > __builtin_free ((void *) D.3528._data); > D.3528._data = 0B; > assign_a_type (, D.3529._data); > } > } > > > I guess I could use some help here (I always tend to get a bit lost in the > trans-stage). Paul, do you by chance have any idea how to handle this > properly? > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #10 from Stefano Zaghi --- Dear all, here https://github.com/szaghi/leaks_hunter you can find my report. Into the report I shown all the test I have done, I provide the sources and the scripts I used to generate them. As FortranFan and Francesco Salvadore pointed out, it seems that a simple workaround exists: add an allocatable into types which have only static components and have polymorphic result-functions. I'll try this workaround into the real program after 25 April. I hope this report you for your patch. My best regards.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 janus at gcc dot gnu.org changed: What|Removed |Added CC||pault at gcc dot gnu.org --- Comment #9 from janus at gcc dot gnu.org --- Anyway, getting back to the discussion of the actual bug ... (In reply to janus from comment #4) > When changing the function result from CLASS to TYPE, this deallocation > seems to be done properly (valgrind shows no leak), and the dump looks like > this: > > [...] Based on this observation, I cooked up a draft patch that tries to modify the code which does the freeing for TYPEs and make it work for CLASSes: Index: gcc/fortran/trans-expr.c === --- gcc/fortran/trans-expr.c(revision 247083) +++ gcc/fortran/trans-expr.c(working copy) @@ -6131,15 +6131,26 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * /* Allocatable scalar function results must be freed and nullified after use. This necessitates the creation of a temporary to hold the result to prevent duplicate calls. */ - if (!byref && sym->ts.type != BT_CHARACTER - && sym->attr.allocatable && !sym->attr.dimension) + if (!byref && sym->ts.type != BT_CHARACTER) { - tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); - gfc_add_modify (>pre, tmp, se->expr); - se->expr = tmp; - tmp = gfc_call_free (tmp); - gfc_add_expr_to_block (, tmp); - gfc_add_modify (, se->expr, build_int_cst (TREE_TYPE (se->expr), 0)); + if (sym->attr.allocatable && !sym->attr.dimension) + { + tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); + gfc_add_modify (>pre, tmp, se->expr); + se->expr = tmp; + gfc_add_expr_to_block (, gfc_call_free (tmp)); + gfc_add_modify (, tmp, build_int_cst (TREE_TYPE (tmp), 0)); + } + else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.allocatable + && !CLASS_DATA (sym)->attr.dimension) + { + tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); + gfc_add_modify (>pre, tmp, se->expr); + se->expr = tmp; + tmp = gfc_class_data_get (tmp); + gfc_add_expr_to_block (, gfc_call_free (tmp)); + gfc_add_modify (, tmp, build_int_cst (TREE_TYPE (tmp), 0)); + } } /* If we have a pointer function, but we don't want a pointer, e.g. Unfortunately it does not work, because it only creates a copy of the class container, but frees up the class data too early: polymorphic_operators_memory_leaks () { static struct a_type_t a = {.x=1.0e+0}; static struct a_type_t b = {.x=2.0e+0}; { struct __class_a_type_m_A_type_t_a D.3528; struct __class_a_type_m_A_type_t_a D.3529; D.3528 = add_a_type (, ); D.3529 = D.3528; __builtin_free ((void *) D.3528._data); D.3528._data = 0B; assign_a_type (, D.3529._data); } } I guess I could use some help here (I always tend to get a bit lost in the trans-stage). Paul, do you by chance have any idea how to handle this properly?
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #8 from Stefano Zaghi --- Dear Janus, > No offense taken. Asking questions is not a crime ;) Good, thank you for the clarification. > I'm sorry to disappoint you, but there simply is no roadmap and I'm not able > to provide one. That's just not how things work with gfortran. > If you absolutely critically depend on some feature being available in a > certain > time-frame, then your best options are probably: > a) Try to implement it yourself or > b) pay someone to implement it. No disappointing at all: this is, indeed, the answer I was searching for taking a decision. If there is not a "timeline" for this bug, because the option a) is not up to me and option b) is currently impossible, this means that I have to left GNU if I cannot find a workaround for the leaks quickly. > I don't think the bug is incredibly difficult to solve. I already have a > basic > understanding of what's missing (see my analysis above) and I might > look into fixing it soon. BUT: I simply can not give you any roadmaps or > guarantees for that. > And yes, gfortran could definitely use some more manpower. If you are willing > to help (or know someone who is), you're certainly welcome. I really would like to help, but I am not up to the task (I never go over tutorial-level with C). Anyhow, if you can share your idea about the issue is placed (files involved, rationale...) it could be a starting a point: I have a colleague well-versed in C, maybe in some eons I could be of some help. > Sure, that will probably help to understand the problem. Thanks for your > efforts. You are much more than welcome. After 25 April I'll provide my report. My best regards.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #7 from janus at gcc dot gnu.org --- (In reply to Stefano Zaghi from comment #6) > As I tried to clarify to Steve, mine was absolutely not a polemic question: No offense taken. Asking questions is not a crime ;) > What I meant was "because the bug is known from 2014, can I conclude that > there are not any developer who takes care (for time/interest lacking) about > this in a reasonable time?". It is just a hint-request about a roadmap I'm sorry to disappoint you, but there simply is no roadmap and I'm not able to provide one. That's just not how things work with gfortran. If you absolutely critically depend on some feature being available in a certain time-frame, then your best options are probably: a) Try to implement it yourself or b) pay someone to implement it. > My concern was that the bug was > very difficult to solve and you are too few to solve it. I don't think the bug is incredibly difficult to solve. I already have a basic understanding of what's missing (see my analysis above) and I might look into fixing it soon. BUT: I simply can not give you any roadmaps or guarantees for that. And yes, gfortran could definitely use some more manpower. If you are willing to help (or know someone who is), you're certainly welcome. > I am going to create a detailed report (within a github repository) taking > into account many combinations: it seems that if I add an allocatable > component alongside the static one, the leaks disappear (although this does > not happen in a real,omplex code where both static and dynamic components > are present). If it is of some help, I would like to share with you. Sure, that will probably help to understand the problem. Thanks for your efforts.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #6 from Stefano Zaghi --- Dear Janus, thank you very much for your help, it is really appreciated. > Note that most gfortran developers actually sacrifice their spare time to > contribute, without receiving any kind of financial reward for it. > I contributed large parts of the OOP implementation when I was a student > (with some funding via GSoC). Nowadays my day job and private life keeps me > from spending too much time on gfotran, but I still try to contribute the > occasional bug fix if I can. As I tried to clarify to Steve, mine was absolutely not a polemic question: although my contributions are definitely not equal to yours, I am also an active FOSS developer doing things for the community spending my free time, I clearly understand the FOSS developing effort. What I meant was "because the bug is known from 2014, can I conclude that there are not any developer who takes care (for time/interest lacking) about this in a reasonable time?". It is just a hint-request about a roadmap (I have to decide how to progress my work, gnu was a key feature), absolutely no critics about you, you are my superheros. My concern was that the bug was very difficult to solve and you are too few to solve it. I am going to create a detailed report (within a github repository) taking into account many combinations: it seems that if I add an allocatable component alongside the static one, the leaks disappear (although this does not happen in a real,omplex code where both static and dynamic components are present). If it is of some help, I would like to share with you. My best regards.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #5 from janus at gcc dot gnu.org --- (In reply to Stefano Zaghi from comment #2) > I read that the other bug report is dated 2014: can I conclude that such a > bug will need a long time to be fixed? Not necessarily. It just takes someone to do it ;) Note that most gfortran developers actually sacrifice their spare time to contribute, without receiving any kind of financial reward for it. I contributed large parts of the OOP implementation when I was a student (with some funding via GSoC). Nowadays my day job and private life keeps me from spending too much time on gfotran, but I still try to contribute the occasional bug fix if I can.
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 --- Comment #4 from janus at gcc dot gnu.org --- (In reply to janus from comment #3) > Confirmed. Here is the most reduced test case I could construct from your > original example: -fdump-tree-original shows the following dump for this case: polymorphic_operators_memory_leaks () { static struct a_type_t a = {.x=1.0e+0}; static struct a_type_t b = {.x=2.0e+0}; { struct __class_a_type_m_A_type_t_a D.3528; D.3528 = add_a_type (, ); assign_a_type (, D.3528._data); } } As you can see we generate a temporary called 'D.3528' for the polymorphic function result. All we have to do is to deallocate this temporary at the end. When changing the function result from CLASS to TYPE, this deallocation seems to be done properly (valgrind shows no leak), and the dump looks like this: polymorphic_operators_memory_leaks () { static struct a_type_t a = {.x=1.0e+0}; static struct a_type_t b = {.x=2.0e+0}; { struct a_type_t * D.3511; struct a_type_t D.3512; D.3511 = add_a_type (, ); D.3512 = *D.3511; __builtin_free ((void *) D.3511); D.3511 = 0B; assign_a_type (, ); } }
[Bug fortran/80477] [OOP] Polymorphic function result generates memory leak
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 janus at gcc dot gnu.org changed: What|Removed |Added Keywords||wrong-code Status|UNCONFIRMED |NEW Last reconfirmed||2017-04-22 CC||janus at gcc dot gnu.org Target Milestone|--- |8.0 Summary|Polymorphic functions (thus |[OOP] Polymorphic function |operators) generates memory |result generates memory |leaks |leak Ever confirmed|0 |1 --- Comment #3 from janus at gcc dot gnu.org --- Confirmed. Here is the most reduced test case I could construct from your original example: module a_type_m implicit none type :: a_type_t real :: x endtype contains subroutine assign_a_type(lhs, rhs) type(a_type_t), intent(inout) :: lhs type(a_type_t), intent(in):: rhs lhs%x = rhs%x end subroutine function add_a_type(lhs, rhs) result( res ) type(a_type_t), intent(in) :: lhs type(a_type_t), intent(in) :: rhs class(a_type_t), allocatable :: res allocate (a_type_t :: res) res%x = lhs%x + rhs%x end function end module program polymorphic_operators_memory_leaks use a_type_m implicit none type(a_type_t) :: a = a_type_t(1) , b = a_type_t(2) call assign_a_type (a, add_a_type(a,b)) ! generates memory leak end valgrind shows the following output for all gfortran versions I tried (from 4.7 to trunk): ==6131== HEAP SUMMARY: ==6131== in use at exit: 4 bytes in 1 blocks ==6131== total heap usage: 20 allocs, 19 frees, 12,012 bytes allocated ==6131== ==6131== LEAK SUMMARY: ==6131==definitely lost: 4 bytes in 1 blocks ==6131==indirectly lost: 0 bytes in 0 blocks I think it's indeed a duplicate of PR 60913.