diff options
Diffstat (limited to 'gcc/fortran/symbol.c')
-rw-r--r-- | gcc/fortran/symbol.c | 53 |
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 |