+2010-07-30 Mikael Morin <mikael@gcc.gnu.org>
+
+ * gfortran.h (gfc_release_symbol): New prototype.
+ * symbol.c (gfc_release_symbol): New. Code taken from free_sym_tree.
+ (gfc_undo_symbols, free_sym_tree, gfc_free_finalizer):
+ Use gfc_release_symbol.
+ * parse.c (gfc_fixup_sibling_symbols): Ditto.
+ * resolve.c (resolve_symbol): Ditto.
+
2010-07-29 Tobias Burnus <burnus@net-b.de>
PR fortran/45087
gfc_user_op *gfc_get_uop (const char *);
gfc_user_op *gfc_find_uop (const char *, gfc_namespace *);
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 **);
}
+/* Decrease the reference counter and free memory when we reach zero. */
+void
+gfc_release_symbol (gfc_symbol *sym)
+{
+ if (sym == NULL)
+ return;
+
+ if (sym->formal_ns != NULL && sym->refs == 2)
+ {
+ /* As formal_ns contains a reference to sym, delete formal_ns just
+ before the deletion of sym. */
+ gfc_namespace *ns = sym->formal_ns;
+ sym->formal_ns = NULL;
+ gfc_free_namespace (ns);
+ }
+
+ sym->refs--;
+ if (sym->refs > 0)
+ return;
+
+ gcc_assert (sym->refs == 0);
+ gfc_free_symbol (sym);
+}
+
+
/* Allocate and initialize a new symbol node. */
gfc_symbol *
gfc_delete_symtree (&p->ns->sym_root, p->name);
- p->refs--;
- if (p->refs < 0)
- gfc_internal_error ("gfc_undo_symbols(): Negative refs");
- if (p->refs == 0)
- gfc_free_symbol (p);
+ gfc_release_symbol (p);
continue;
}
static void
free_sym_tree (gfc_symtree *sym_tree)
{
- gfc_namespace *ns;
- gfc_symbol *sym;
-
if (sym_tree == NULL)
return;
free_sym_tree (sym_tree->left);
free_sym_tree (sym_tree->right);
- sym = sym_tree->n.sym;
-
- sym->refs--;
- if (sym->refs < 0)
- gfc_internal_error ("free_sym_tree(): Negative refs");
-
- if (sym->formal_ns != NULL && sym->refs == 1)
- {
- /* As formal_ns contains a reference to sym, delete formal_ns just
- before the deletion of sym. */
- ns = sym->formal_ns;
- sym->formal_ns = NULL;
- gfc_free_namespace (ns);
- }
- else if (sym->refs == 0)
- {
- /* Go ahead and delete the symbol. */
- gfc_free_symbol (sym);
- }
-
+ gfc_release_symbol (sym_tree->n.sym);
gfc_free (sym_tree);
}
{
if (el)
{
- if (el->proc_sym)
- {
- --el->proc_sym->refs;
- if (!el->proc_sym->refs)
- gfc_free_symbol (el->proc_sym);
- }
-
+ gfc_release_symbol (el->proc_sym);
gfc_free (el);
}
}