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

via flang-commits flang-commits at lists.llvm.org
Sun Jun 21 19:51:21 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Eugene Epshteyn (eugeneepshteyn)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/205023.diff


4 Files Affected:

- (modified) flang/lib/Semantics/check-call.cpp (+7-2) 
- (modified) flang/lib/Semantics/check-call.h (+6-1) 
- (modified) flang/lib/Semantics/expression.cpp (+4-4) 
- (modified) flang/test/Semantics/call47.f90 (+12) 


``````````diff
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 709292e62f97c..6c0a21cc769c1 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3791,7 +3791,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;
@@ -3864,13 +3863,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 F2023 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

``````````

</details>


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


More information about the flang-commits mailing list