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

Reply via email to