]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/41093 (memory leaks with gfc_namespace)
authorTobias Burnus <burnus@net-b.de>
Mon, 27 Aug 2012 12:07:43 +0000 (14:07 +0200)
committerTobias Burnus <burnus@gcc.gnu.org>
Mon, 27 Aug 2012 12:07:43 +0000 (14:07 +0200)
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

gcc/fortran/ChangeLog
gcc/fortran/decl.c
gcc/fortran/gfortran.h
gcc/fortran/match.c
gcc/fortran/module.c
gcc/fortran/parse.c
gcc/fortran/resolve.c
gcc/fortran/symbol.c

index eff252cb465db53d94f8d89916efb1408cb77f28..b6600735ef45facbe147e31659bced8a89b2c41f 100644 (file)
@@ -1,3 +1,20 @@
+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
index 87eb8a0bb24f184d7050325ecaa3546214c3aec0..efd21dc7ec713b06c93c2746d1f0cd243e1a954f 100644 (file)
@@ -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)
     {
index 4c8a856e210b35852d705957a7893fd1e1067655..d67d57b7b137325cc67f0f30a27249f00c94f34a 100644 (file)
@@ -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;
 
index 0b1cf5a3dbb73c391ea56f78f0b34a02cafdd8d5..4c713a5d6cb83edd988855abc7000e7ad43d19a4 100644 (file)
@@ -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
index a4ff1998036672e12617c465c8bdb2981a2219ff..bfd8b01ea09af0e33c307bcf232c8328af36bd0f 100644 (file)
@@ -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.  */
index c0ec6e4d85f2e59ed9bf60f00e74b40b3e9caa56..5c5d38176c370fdb5a17e2738c1923ff18087657 100644 (file)
@@ -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;
 
index c9be70e020646460f7ea8179f7d2858e266192bb..63b730c6e3b2456774c058f651031a061baca2c6 100644 (file)
@@ -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++;
        }
     }
 
index 5a1e5adb85c7cd1c66ac0ad71f8d84fa75edcdf8..4d030b76fc1ed85addc93a35aa12dccfbfd4390a 100644 (file)
@@ -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.  */