https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477
--- Comment #11 from paul.richard.thomas at gmail dot com <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 (&post, gfc_call_free (tmp));/gfc_add_expr_to_block (&se->post, gfc_call_free (tmp)); Cheers Paul On 23 April 2017 at 12:02, janus at gcc dot gnu.org <gcc-bugzi...@gcc.gnu.org> wrote: > 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 (&se->pre, tmp, se->expr); > - se->expr = tmp; > - tmp = gfc_call_free (tmp); > - gfc_add_expr_to_block (&post, tmp); > - gfc_add_modify (&post, 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 (&se->pre, tmp, se->expr); > + se->expr = tmp; > + gfc_add_expr_to_block (&post, gfc_call_free (tmp)); > + gfc_add_modify (&post, 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 (&se->pre, tmp, se->expr); > + se->expr = tmp; > + tmp = gfc_class_data_get (tmp); > + gfc_add_expr_to_block (&post, gfc_call_free (tmp)); > + gfc_add_modify (&post, 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 (&a, &b); > D.3529 = D.3528; > __builtin_free ((void *) D.3528._data); > D.3528._data = 0B; > assign_a_type (&a, 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.