On 1/16/26 2:21 PM, Jerry D wrote:
The following fix provided by Steve.

Fairly self explanatory.

Regression tested x86_64-linux.

OK for mainline? Copied release manager as we are in Stage 4.

Regards,


Updated the patch per Steve to include a check for functions as well as 
subroutines.

Regression tested again. OK for mainline.

    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 --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index be72132c79d..0c52511790f 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 00000000000..b9984cad107
--- /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