aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/symbol.c')
-rw-r--r--gcc/fortran/symbol.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 08bdf18..b7d5b86 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1539,7 +1539,7 @@ gfc_add_procedure (symbol_attribute *attr, procedure_type t,
if (where == NULL)
where = &gfc_current_locus;
- if (attr->proc != PROC_UNKNOWN)
+ if (attr->proc != PROC_UNKNOWN && !attr->module_procedure)
{
gfc_error ("%s procedure at %L is already declared as %s procedure",
gfc_code2string (procedures, t), where,
@@ -1655,10 +1655,15 @@ bool
gfc_add_explicit_interface (gfc_symbol *sym, ifsrc source,
gfc_formal_arglist * formal, locus *where)
{
-
if (check_used (&sym->attr, sym->name, where))
return false;
+ /* Skip the following checks in the case of a module_procedures in a
+ submodule since they will manifestly fail. */
+ if (sym->attr.module_procedure == 1
+ && source == IFSRC_DECL)
+ goto finish;
+
if (where == NULL)
where = &gfc_current_locus;
@@ -1677,6 +1682,7 @@ gfc_add_explicit_interface (gfc_symbol *sym, ifsrc source,
return false;
}
+finish:
sym->formal = formal;
sym->attr.if_source = source;
@@ -1703,7 +1709,10 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
if (sym->attr.result && type == BT_UNKNOWN && sym->ns->proc_name)
type = sym->ns->proc_name->ts.type;
- if (type != BT_UNKNOWN && !(sym->attr.function && sym->attr.implicit_type))
+ if (type != BT_UNKNOWN && !(sym->attr.function && sym->attr.implicit_type)
+ && !(gfc_state_stack->previous && gfc_state_stack->previous->previous
+ && gfc_state_stack->previous->previous->state == COMP_SUBMODULE)
+ && !sym->attr.module_procedure)
{
if (sym->attr.use_assoc)
gfc_error ("Symbol %qs at %L conflicts with symbol from module %qs, "
@@ -1876,6 +1885,44 @@ fail:
}
+/* A function to generate a dummy argument symbol using that from the
+ interface declaration. Can be used for the result symbol as well if
+ the flag is set. */
+
+int
+gfc_copy_dummy_sym (gfc_symbol **dsym, gfc_symbol *sym, int result)
+{
+ int rc;
+
+ rc = gfc_get_symbol (sym->name, NULL, dsym);
+ if (rc)
+ return rc;
+
+ if (!gfc_add_type (*dsym, &(sym->ts), &gfc_current_locus))
+ return 1;
+
+ if (!gfc_copy_attr (&(*dsym)->attr, &(sym->attr),
+ &gfc_current_locus))
+ return 1;
+
+ if ((*dsym)->attr.dimension)
+ (*dsym)->as = gfc_copy_array_spec (sym->as);
+
+ (*dsym)->attr.class_ok = sym->attr.class_ok;
+
+ if ((*dsym) != NULL && !result
+ && (!gfc_add_dummy(&(*dsym)->attr, (*dsym)->name, NULL)
+ || !gfc_missing_attr (&(*dsym)->attr, NULL)))
+ return 1;
+ else if ((*dsym) != NULL && result
+ && (!gfc_add_result(&(*dsym)->attr, (*dsym)->name, NULL)
+ || !gfc_missing_attr (&(*dsym)->attr, NULL)))
+ return 1;
+
+ return 0;
+}
+
+
/************** Component name management ************/
/* Component names of a derived type form their own little namespaces