[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:28:45 PDT 2026
https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/205023
>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 1/2] [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
>From 8ae6d83946365d22d5c316ed0652efe10b535299 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 21 Jun 2026 22:28:34 -0400
Subject: [PATCH 2/2] Fixed a comment
---
flang/lib/Semantics/expression.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 6318a6ab24b24..6c0a21cc769c1 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3865,7 +3865,7 @@ std::optional<characteristics::Procedure> ExpressionAnalyzer::CheckCall(
if (isStatementFunction) {
// 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.
+ // requirements of F2023 15.4.2.2.
parser::ContextualMessages &messages{
context_.foldingContext().messages()};
for (auto &arg : arguments) {
More information about the flang-commits
mailing list