https://gcc.gnu.org/g:4d43468377cc6ea907823197dd63428f641c0cd7
commit r16-6855-g4d43468377cc6ea907823197dd63428f641c0cd7 Author: Steven G. Kargl <[email protected]> Date: Fri Jan 16 18:09:56 2026 -0800 Fortran: Fix accepts invalid implicit none (external) This patch yields an error for the test case which was previously being accepted even though implicit none (external) was being specified. PR fortran/109512 gcc/fortran/ChangeLog: * resolve.cc (resolve_function): Check if an external attribute is required on a call to an external procedure. (resolve_call): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/pr109512.f90: New test. Diff: --- gcc/fortran/resolve.cc | 24 ++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/pr109512.f90 | 10 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index be72132c79dc..0c52511790f3 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -3687,6 +3687,20 @@ resolve_function (gfc_expr *expr) gfc_warning (OPT_Wdeprecated_declarations, "Using function %qs at %L is deprecated", sym->name, &expr->where); + + /* Check an external function supplied as a dummy argument has an external + attribute when a program unit uses 'implicit none (external)'. */ + if (expr->expr_type == EXPR_FUNCTION + && expr->symtree + && expr->symtree->n.sym->attr.dummy + && expr->symtree->n.sym->ns->has_implicit_none_export + && !gfc_is_intrinsic(expr->symtree->n.sym, 0, expr->where)) + { + gfc_error ("Dummy procedure %qs at %L requires an EXTERNAL attribute", + sym->name, &expr->where); + return false; + } + return t; } @@ -4167,6 +4181,16 @@ resolve_call (gfc_code *c) /* Resume assumed_size checking. */ need_full_assumed_size--; + /* If 'implicit none (external)' and the symbol is a dummy argument, + check for an 'external' attribute. */ + if (csym->ns->has_implicit_none_export + && csym->attr.external == 0 && csym->attr.dummy == 1) + { + gfc_error ("Dummy procedure %qs at %L requires an EXTERNAL attribute", + csym->name, &c->loc); + return false; + } + /* If external, check for usage. */ if (csym && is_external_proc (csym)) resolve_global_procedure (csym, &c->loc, 1); diff --git a/gcc/testsuite/gfortran.dg/pr109512.f90 b/gcc/testsuite/gfortran.dg/pr109512.f90 new file mode 100644 index 000000000000..b9984cad107d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr109512.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +subroutine foo(bar) + implicit none (external) + call bar(1) ! { dg-error "requires an EXTERNAL attribute" } +end subroutine foo + +function bah(bar) + implicit none (external) + foo = bar(1) ! { dg-error "requires an EXTERNAL attribute" } +end function bah
