From 6f79f4d1d6c6e3dcb0231404969882726d31a50c Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Mon, 27 Aug 2012 14:07:43 +0200 Subject: re PR fortran/41093 (memory leaks with gfc_namespace) 2012-08-27 Tobias Burnus PR fortran/41093 * gfortran.h (gfc_common_head): Add "int refs". * match.c (gfc_match_common): Increment refs. * resolve.c (resolve_symbol): Only increment formal_ns->refs if formal_ns is not sym->ns. * symbol.c (gfc_free_symbol): Only free formal_ns if if formal_ns is not sym->ns. Free common_block if refs is one. (gfc_release_symbol): Release formal_ns only if the symbol is not ENTRY of a module. * decl.c (get_proc_name): Don't increment gfc_current_ns->refs. * parse.c (parse_interface): Incement proc_unit->refs++ for proc-pointer result variables. * module.c (mio_symbol): Don't increase sym->refs for its use in sym->formal_ns->proc_name. From-SVN: r190710 --- gcc/fortran/ChangeLog | 17 +++++++++++++++++ gcc/fortran/decl.c | 1 - gcc/fortran/gfortran.h | 1 + gcc/fortran/match.c | 1 + gcc/fortran/module.c | 5 +---- gcc/fortran/parse.c | 8 +++++--- gcc/fortran/resolve.c | 3 ++- gcc/fortran/symbol.c | 13 +++++++++++-- 8 files changed, 38 insertions(+), 11 deletions(-) (limited to 'gcc/fortran') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index eff252c..b660073 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,22 @@ 2012-08-27 Tobias Burnus + PR fortran/41093 + * gfortran.h (gfc_common_head): Add "int refs". + * match.c (gfc_match_common): Increment refs. + * resolve.c (resolve_symbol): Only increment formal_ns->refs + if formal_ns is not sym->ns. + * symbol.c (gfc_free_symbol): Only free formal_ns if + if formal_ns is not sym->ns. Free common_block if refs is one. + (gfc_release_symbol): Release formal_ns only if the + symbol is not ENTRY of a module. + * decl.c (get_proc_name): Don't increment gfc_current_ns->refs. + * parse.c (parse_interface): Incement proc_unit->refs++ for + proc-pointer result variables. + * module.c (mio_symbol): Don't increase sym->refs for its + use in sym->formal_ns->proc_name. + +2012-08-27 Tobias Burnus + PR fortran/54370 * trans-stmt.c (gfc_trans_do_while): Don't change the logical kind for negation of the condition. diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 87eb8a0..efd21dc 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -891,7 +891,6 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry) return rc; sym = *result; - gfc_current_ns->refs++; if (sym && !sym->gfc_new && gfc_current_state () != COMP_INTERFACE) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 4c8a856..d67d57b 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1266,6 +1266,7 @@ typedef struct gfc_common_head struct gfc_symbol *head; const char* binding_label; int is_bind_c; + int refs; } gfc_common_head; diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 0b1cf5a..4c713a5 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -4398,6 +4398,7 @@ gfc_match_common (void) /* Store a ref to the common block for error checking. */ sym->common_block = t; + sym->common_block->refs++; /* See if we know the current common block is bind(c), and if so, then see if we can check if the symbol is (which it'll diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index a4ff199..bfd8b01 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -3807,10 +3807,7 @@ mio_symbol (gfc_symbol *sym) { mio_namespace_ref (&sym->formal_ns); if (sym->formal_ns) - { - sym->formal_ns->proc_name = sym; - sym->refs++; - } + sym->formal_ns->proc_name = sym; } /* Save/restore common block links. */ diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index c0ec6e4..5c5d381 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -2363,7 +2363,6 @@ parse_interface (void) gfc_interface_info save; gfc_state_data s1, s2; gfc_statement st; - locus proc_locus; accept_statement (ST_INTERFACE); @@ -2452,7 +2451,9 @@ loop: accept_statement (st); prog_unit = gfc_new_block; prog_unit->formal_ns = gfc_current_ns; - proc_locus = gfc_current_locus; + if (prog_unit == prog_unit->formal_ns->proc_name + && prog_unit->ns != prog_unit->formal_ns) + prog_unit->refs++; decl: /* Read data declaration statements. */ @@ -2493,7 +2494,8 @@ decl: && strcmp (current_interface.ns->proc_name->name, prog_unit->name) == 0) gfc_error ("INTERFACE procedure '%s' at %L has the same name as the " - "enclosing procedure", prog_unit->name, &proc_locus); + "enclosing procedure", prog_unit->name, + ¤t_interface.ns->proc_name->declared_at); goto loop; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index c9be70e0..63b730c 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -13086,7 +13086,8 @@ resolve_symbol (gfc_symbol *sym) if (formal) { sym->formal_ns = formal->sym->ns; - sym->formal_ns->refs++; + if (sym->ns != formal->sym->ns) + sym->formal_ns->refs++; } } diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 5a1e5ad..4d030b7 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -2511,7 +2511,8 @@ gfc_free_symbol (gfc_symbol *sym) gfc_free_namelist (sym->namelist); - gfc_free_namespace (sym->formal_ns); + if (sym->ns != sym->formal_ns) + gfc_free_namespace (sym->formal_ns); if (!sym->attr.generic_copy) gfc_free_interface (sym->generic); @@ -2520,6 +2521,13 @@ gfc_free_symbol (gfc_symbol *sym) gfc_free_namespace (sym->f2k_derived); + if (sym->common_block && sym->common_block->name[0] != '\0') + { + sym->common_block->refs--; + if (sym->common_block->refs == 0) + free (sym->common_block); + } + free (sym); } @@ -2532,7 +2540,8 @@ gfc_release_symbol (gfc_symbol *sym) if (sym == NULL) return; - if (sym->formal_ns != NULL && sym->refs == 2) + if (sym->formal_ns != NULL && sym->refs == 2 && sym->formal_ns != sym->ns + && (!sym->attr.entry || !sym->module)) { /* As formal_ns contains a reference to sym, delete formal_ns just before the deletion of sym. */ -- cgit v1.1