+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
return rc;
sym = *result;
- gfc_current_ns->refs++;
if (sym && !sym->gfc_new && gfc_current_state () != COMP_INTERFACE)
{
struct gfc_symbol *head;
const char* binding_label;
int is_bind_c;
+ int refs;
}
gfc_common_head;
/* 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
{
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. */
gfc_interface_info save;
gfc_state_data s1, s2;
gfc_statement st;
- locus proc_locus;
accept_statement (ST_INTERFACE);
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. */
&& 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;
if (formal)
{
sym->formal_ns = formal->sym->ns;
- sym->formal_ns->refs++;
+ if (sym->ns != formal->sym->ns)
+ sym->formal_ns->refs++;
}
}
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);
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);
}
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. */