[flang-commits] [flang] [flang][Semantics] Do not require explicit interface checks for statement functions (PR #205023)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Sun Jun 21 19:25:54 PDT 2026


https://github.com/eugeneepshteyn created https://github.com/llvm/llvm-project/pull/205023

https://github.com/llvm/llvm-project/pull/198610 caused a regression, where the
code path for explicit interface checks was also used for the statement
functions arg check. Refactor the code to avoid explicit interface checks.

Fixes #203500

>From f7563b696fc611d1e8b51ca020e2ce068c6e311a Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Fri, 12 Jun 2026 07:34:39 -0400
Subject: [PATCH] [flang][Semantics] Do not require explicit interface checks
 for statement functions

https://github.com/llvm/llvm-project/pull/198610 caused a regression, where the
code path for explicit interface checks was also used for the statement
functions arg check. Refactor the code to avoid explicit interface checks.

Fixes #203500
---
 flang/lib/Semantics/check-call.cpp |  9 +++++++--
 flang/lib/Semantics/check-call.h   |  7 ++++++-
 flang/lib/Semantics/expression.cpp |  8 ++++----
 flang/test/Semantics/call47.f90    | 12 ++++++++++++
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index dcd7dc4288f6f..7b4f0b71b7a40 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -27,8 +27,8 @@ namespace characteristics = Fortran::evaluate::characteristics;
 
 namespace Fortran::semantics {
 
-void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
-    parser::ContextualMessages &messages, SemanticsContext &context) {
+void CheckImplicitInterfaceArgKeywords(
+    evaluate::ActualArgument &arg, parser::ContextualMessages &messages) {
   auto restorer{
       messages.SetLocation(arg.sourceLocation().value_or(messages.at()))};
   if (auto kw{arg.keyword()}) {
@@ -36,6 +36,11 @@ void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
         "Keyword '%s=' may not appear in a reference to a procedure with an implicit interface"_err_en_US,
         *kw);
   }
+}
+
+void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
+    parser::ContextualMessages &messages, SemanticsContext &context) {
+  CheckImplicitInterfaceArgKeywords(arg, messages);
   auto type{arg.GetType()};
   if (type) {
     if (type->IsAssumedType()) {
diff --git a/flang/lib/Semantics/check-call.h b/flang/lib/Semantics/check-call.h
index fb021d23dabc8..46943c33a8501 100644
--- a/flang/lib/Semantics/check-call.h
+++ b/flang/lib/Semantics/check-call.h
@@ -25,8 +25,13 @@ namespace Fortran::semantics {
 class Scope;
 class SemanticsContext;
 
+// Check keyword constraints on actual arguments for procedures with implicit
+// interfaces.
+void CheckImplicitInterfaceArgKeywords(
+    evaluate::ActualArgument &, parser::ContextualMessages &);
+
 // Check constraints on actual arguments for procedures with implicit
-// interfaces. Used for statement function calls and external procedures.
+// interfaces.
 void CheckImplicitInterfaceArg(evaluate::ActualArgument &,
     parser::ContextualMessages &, SemanticsContext &);
 
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 66eeaae2c9ff1..9e6f976b4c024 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3778,7 +3778,6 @@ std::optional<characteristics::Procedure> ExpressionAnalyzer::CheckCall(
   bool treatExternalAsImplicit{
       IsExternalCalledImplicitly(callSite, proc.GetSymbol())};
   const Symbol *procSymbol{proc.GetSymbol()};
-  // Statement functions have implicit interfaces and require the same checks
   bool isStatementFunction{
       procSymbol && procSymbol->flags().test(Symbol::Flag::StmtFunction)};
   std::optional<characteristics::Procedure> chars;
@@ -3851,13 +3850,14 @@ std::optional<characteristics::Procedure> ExpressionAnalyzer::CheckCall(
       }
     }
     if (isStatementFunction) {
-      // Statement functions have implicit interfaces; check for
-      // keyword arguments and other implicit interface constraints
+      // Statement functions have implicit interfaces, so keyword actual
+      // arguments are not allowed. They are exempt from the explicit-interface
+      // requirements of 15.4.2.2.
       parser::ContextualMessages &messages{
           context_.foldingContext().messages()};
       for (auto &arg : arguments) {
         if (arg) {
-          semantics::CheckImplicitInterfaceArg(*arg, messages, context_);
+          semantics::CheckImplicitInterfaceArgKeywords(*arg, messages);
         }
       }
     }
diff --git a/flang/test/Semantics/call47.f90 b/flang/test/Semantics/call47.f90
index 0c6e9071f33f0..f247bd5d6b28b 100644
--- a/flang/test/Semantics/call47.f90
+++ b/flang/test/Semantics/call47.f90
@@ -24,3 +24,15 @@ program test_stmt_func_keyword
   !ERROR: Keyword 'y=' may not appear in a reference to a procedure with an implicit interface
   c = f2(x=10, y=20)
 end program
+
+subroutine pdt_actual_to_stmt_func()
+  type t(k)
+    integer, kind :: k = 1
+  end type
+
+  type(t) :: x
+  integer :: f
+
+  f(x) = 0
+  print *, f(x)
+end subroutine



More information about the flang-commits mailing list