diff options
Diffstat (limited to 'gcc/fortran/interface.cc')
-rw-r--r-- | gcc/fortran/interface.cc | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc index 6258a41..1e552a3 100644 --- a/gcc/fortran/interface.cc +++ b/gcc/fortran/interface.cc @@ -2534,16 +2534,33 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, gfc_find_symbol (actual_name, gsym->ns, 0, &global_asym); if (global_asym != NULL) { - gcc_assert (formal->attr.function); - if (!gfc_compare_types (&global_asym->ts, &formal->ts)) + if (formal->attr.subroutine) { - gfc_error ("Type mismatch at %L passing global " - "function %qs declared at %L (%s/%s)", - &actual->where, actual_name, &gsym->where, - gfc_typename (&global_asym->ts), - gfc_dummy_typename (&formal->ts)); + gfc_error ("Mismatch between subroutine and " + "function at %L", &actual->where); return false; } + else if (formal->attr.function) + { + if (!gfc_compare_types (&global_asym->ts, + &formal->ts)) + { + gfc_error ("Type mismatch at %L passing global " + "function %qs declared at %L (%s/%s)", + &actual->where, actual_name, + &gsym->where, + gfc_typename (&global_asym->ts), + gfc_dummy_typename (&formal->ts)); + return false; + } + } + else + { + /* The global symbol is a function. Set the formal + argument acordingly. */ + formal->attr.function = 1; + formal->ts = global_asym->ts; + } } } } @@ -3382,7 +3399,11 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, return false; } else - a->associated_dummy = get_nonintrinsic_dummy_arg (f); + { + if (a->associated_dummy) + free (a->associated_dummy); + a->associated_dummy = get_nonintrinsic_dummy_arg (f); + } if (a->expr == NULL) { |