On Wed, 27 Oct 2021 23:39:43 +0200
Bernhard Reutner-Fischer <rep.dot....@gmail.com> wrote:

> Ping
> [hmz. it's been a while, I'll rebase and retest this one.
> Ok if it passes?]
Testing passed without any new regressions.
Ok for trunk?
thanks,
> 
> On Mon, 15 Oct 2018 10:23:06 +0200
> Bernhard Reutner-Fischer <rep.dot....@gmail.com> wrote:
> 
> > 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.
> > 
> > Regtests cleanly, installed to the fortran-fe-stringpool branch, sent
> > here for reference and later inclusion.
> > I might plug a few more leaks in preparation of switching to hash-maps.
> > I fear that the leaks around interfaces are another candidate ;)
> > 
> > Should probably add a tag for the compile-time leak PR68800 shouldn't i.
> > 
> > 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  <al...@gcc.gnu.org>
> > 
> >     * class.c (generate_finalization_wrapper): Do 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.
> > ---
> >  gcc/fortran/class.c    | 25 +++++++++----------------
> >  gcc/fortran/expr.c     |  2 +-
> >  gcc/fortran/gfortran.h |  6 +++---
> >  gcc/fortran/symbol.c   | 19 ++++++++++---------
> >  4 files changed, 23 insertions(+), 29 deletions(-)
> > 
> > diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
> > index 69c95fc5dfa..e0bb381a55f 100644
> > --- a/gcc/fortran/class.c
> > +++ b/gcc/fortran/class.c
> > @@ -1533,7 +1533,6 @@ generate_finalization_wrapper (gfc_symbol *derived, 
> > gfc_namespace *ns,
> >    gfc_code *last_code, *block;
> >    const char *name;
> >    bool finalizable_comp = false;
> > -  bool expr_null_wrapper = false;
> >    gfc_expr *ancestor_wrapper = NULL, *rank;
> >    gfc_iterator *iter;
> >  
> > @@ -1561,13 +1560,17 @@ generate_finalization_wrapper (gfc_symbol *derived, 
> > gfc_namespace *ns,
> >      }
> >  
> >    /* No wrapper of the ancestor and no own FINAL subroutines and 
> > allocatable
> > -     components: Return a NULL() expression; we defer this a bit to have 
> > have
> > +     components: Return a NULL() expression; we defer this a bit to have
> >       an interface declaration.  */
> >    if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
> >        && !derived->attr.alloc_comp
> >        && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
> >        && !has_finalizer_component (derived))
> > -    expr_null_wrapper = true;
> > +    {
> > +      vtab_final->initializer = gfc_get_null_expr (NULL);
> > +      gcc_assert (vtab_final->ts.interface == NULL);
> > +      return;
> > +    }
> >    else
> >      /* Check whether there are new allocatable components.  */
> >      for (comp = derived->components; comp; comp = comp->next)
> > @@ -1581,7 +1584,7 @@ generate_finalization_wrapper (gfc_symbol *derived, 
> > gfc_namespace *ns,
> >  
> >    /* If there is no new finalizer and no new allocatable, return with
> >       an expr to the ancestor's one.  */
> > -  if (!expr_null_wrapper && !finalizable_comp
> > +  if (!finalizable_comp
> >        && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
> >      {
> >        gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
> > @@ -1605,8 +1608,7 @@ generate_finalization_wrapper (gfc_symbol *derived, 
> > gfc_namespace *ns,
> >    /* Set up the namespace.  */
> >    sub_ns = gfc_get_namespace (ns, 0);
> >    sub_ns->sibling = ns->contained;
> > -  if (!expr_null_wrapper)
> > -    ns->contained = sub_ns;
> > +  ns->contained = sub_ns;
> >    sub_ns->resolved = 1;
> >  
> >    /* Set up the procedure symbol.  */
> > @@ -1622,7 +1624,7 @@ generate_finalization_wrapper (gfc_symbol *derived, 
> > gfc_namespace *ns,
> >    final->ts.kind = 4;
> >    final->attr.artificial = 1;
> >    final->attr.always_explicit = 1;
> > -  final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
> > +  final->attr.if_source = IFSRC_DECL;
> >    if (ns->proc_name->attr.flavor == FL_MODULE)
> >      final->module = ns->proc_name->name;
> >    gfc_set_sym_referenced (final);
> > @@ -1672,15 +1674,6 @@ generate_finalization_wrapper (gfc_symbol *derived, 
> > gfc_namespace *ns,
> >    final->formal->next->next->sym = fini_coarray;
> >    gfc_commit_symbol (fini_coarray);
> >  
> > -  /* Return with a NULL() expression but with an interface which has
> > -     the formal arguments.  */
> > -  if (expr_null_wrapper)
> > -    {
> > -      vtab_final->initializer = gfc_get_null_expr (NULL);
> > -      vtab_final->ts.interface = final;
> > -      return;
> > -    }
> > -
> >    /* Local variables.  */
> >  
> >    gfc_get_symbol (gfc_get_string ("%s", "idx"), sub_ns, &idx);
> > diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
> > index cc12e0a8402..3d744ec9641 100644
> > --- a/gcc/fortran/expr.c
> > +++ b/gcc/fortran/expr.c
> > @@ -533,7 +533,7 @@ gfc_free_actual_arglist (gfc_actual_arglist *a1)
> >      {
> >        a2 = a1->next;
> >        if (a1->expr)
> > -      gfc_free_expr (a1->expr);
> > +   gfc_free_expr (a1->expr);
> >        free (a1);
> >        a1 = a2;
> >      }
> > diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
> > index 4612835706b..3466c42132f 100644
> > --- a/gcc/fortran/gfortran.h
> > +++ b/gcc/fortran/gfortran.h
> > @@ -3032,8 +3032,8 @@ gfc_user_op *gfc_get_uop (const char *);
> >  gfc_user_op *gfc_find_uop (const char *, gfc_namespace *);
> >  const char *gfc_get_uop_from_name (const char*);
> >  const char *gfc_get_name_from_uop (const char*);
> > -void gfc_free_symbol (gfc_symbol *);
> > -void gfc_release_symbol (gfc_symbol *);
> > +void gfc_free_symbol (gfc_symbol *&);
> > +void gfc_release_symbol (gfc_symbol *&);
> >  gfc_symbol *gfc_new_symbol (const char *, gfc_namespace *);
> >  gfc_symtree* gfc_find_symtree_in_proc (const char *, gfc_namespace *);
> >  int gfc_find_symbol (const char *, gfc_namespace *, int, gfc_symbol **);
> > @@ -3058,7 +3058,7 @@ void gfc_commit_symbols (void);
> >  void gfc_commit_symbol (gfc_symbol *);
> >  gfc_charlen *gfc_new_charlen (gfc_namespace *, gfc_charlen *);
> >  void gfc_free_charlen (gfc_charlen *, gfc_charlen *);
> > -void gfc_free_namespace (gfc_namespace *);
> > +void gfc_free_namespace (gfc_namespace *&);
> >  
> >  void gfc_symbol_init_2 (void);
> >  void gfc_symbol_done_2 (void);
> > diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
> > index 09ad2bbf0cd..c99c106a0c0 100644
> > --- a/gcc/fortran/symbol.c
> > +++ b/gcc/fortran/symbol.c
> > @@ -2590,8 +2590,9 @@ free_components (gfc_component *p)
> >     gfc_free_expr (p->kind_expr);
> >        if (p->param_list)
> >     gfc_free_actual_arglist (p->param_list);
> > -      free (p->tb);
> >  
> > +      free (p->tb);
> > +      p->tb = NULL;
> >        free (p);
> >      }
> >  }
> > @@ -3070,7 +3071,7 @@ set_symbol_common_block (gfc_symbol *sym, 
> > gfc_common_head *common_block)
> >  /* Remove a gfc_symbol structure and everything it points to.  */
> >  
> >  void
> > -gfc_free_symbol (gfc_symbol *sym)
> > +gfc_free_symbol (gfc_symbol *&sym)
> >  {
> >  
> >    if (sym == NULL)
> > @@ -3078,8 +3079,6 @@ gfc_free_symbol (gfc_symbol *sym)
> >  
> >    gfc_free_array_spec (sym->as);
> >  
> > -  free_components (sym->components);
> > -
> >    gfc_free_expr (sym->value);
> >  
> >    gfc_free_namelist (sym->namelist);
> > @@ -3094,19 +3093,22 @@ gfc_free_symbol (gfc_symbol *sym)
> >  
> >    gfc_free_namespace (sym->f2k_derived);
> >  
> > +  free_components (sym->components);
> > +
> >    set_symbol_common_block (sym, NULL);
> >  
> >    if (sym->param_list)
> >      gfc_free_actual_arglist (sym->param_list);
> >  
> >    free (sym);
> > +  sym = NULL;
> >  }
> >  
> >  
> >  /* Decrease the reference counter and free memory when we reach zero.  */
> >  
> >  void
> > -gfc_release_symbol (gfc_symbol *sym)
> > +gfc_release_symbol (gfc_symbol *&sym)
> >  {
> >    if (sym == NULL)
> >      return;
> > @@ -3826,10 +3828,8 @@ free_tb_tree (gfc_symtree *t)
> >  
> >    free_tb_tree (t->left);
> >    free_tb_tree (t->right);
> > -
> > -  /* TODO: Free type-bound procedure structs themselves; probably needs 
> > some
> > -     sort of ref-counting mechanism.  */
> >    free (t->n.tb);
> > +  t->n.tb = NULL;
> >    free (t);
> >  }
> >  
> > @@ -4019,7 +4019,7 @@ free_entry_list (gfc_entry_list *el)
> >     taken care of when a specific name is freed.  */
> >  
> >  void
> > -gfc_free_namespace (gfc_namespace *ns)
> > +gfc_free_namespace (gfc_namespace *&ns)
> >  {
> >    gfc_namespace *p, *q;
> >    int i;
> > @@ -4057,6 +4057,7 @@ gfc_free_namespace (gfc_namespace *ns)
> >    gfc_free_data (ns->data);
> >    p = ns->contained;
> >    free (ns);
> > +  ns = NULL;
> >  
> >    /* Recursively free any contained namespaces.  */
> >    while (p != NULL)  
> 

Reply via email to