aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTobias Burnus <burnus@net-b.de>2012-08-27 14:07:43 +0200
committerTobias Burnus <burnus@gcc.gnu.org>2012-08-27 14:07:43 +0200
commit6f79f4d1d6c6e3dcb0231404969882726d31a50c (patch)
tree35954802481b336b7827eb81f61dda5ed4be17f6 /gcc
parent1d6368551e85cac41df6df4234d865918b693319 (diff)
downloadgcc-6f79f4d1d6c6e3dcb0231404969882726d31a50c.zip
gcc-6f79f4d1d6c6e3dcb0231404969882726d31a50c.tar.gz
gcc-6f79f4d1d6c6e3dcb0231404969882726d31a50c.tar.bz2
re PR fortran/41093 (memory leaks with gfc_namespace)
2012-08-27 Tobias Burnus <burnus@net-b.de> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog17
-rw-r--r--gcc/fortran/decl.c1
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/match.c1
-rw-r--r--gcc/fortran/module.c5
-rw-r--r--gcc/fortran/parse.c8
-rw-r--r--gcc/fortran/resolve.c3
-rw-r--r--gcc/fortran/symbol.c13
8 files changed, 38 insertions, 11 deletions
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 <burnus@net-b.de>
+ 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 <burnus@net-b.de>
+
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,
+ &current_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. */