[flang-commits] [flang] [flang] Don't allow function calls to PROCEDURE() (PR #165786)
via flang-commits
flang-commits at lists.llvm.org
Thu Oct 30 14:57:29 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
PROCEDURE() declares a procedure with no interface or result type. (When used to declare a derived type component, it must also be a NOPASS POINTER.) Document that we allow such procedures to be called as subroutines with implicit interfaces, despite the ISO standard -- this is a universal extension to the language.
However, no longer allow such procedure entities to be referenced as implicitly-typed functions -- this usage is neither portable nor well-defined, as the compilers that do allow it do not respect the implicit typing rules established at the point of declaration.
---
Full diff: https://github.com/llvm/llvm-project/pull/165786.diff
3 Files Affected:
- (modified) flang/docs/Extensions.md (+7-1)
- (modified) flang/lib/Semantics/resolve-names.cpp (+12-7)
- (modified) flang/test/Semantics/resolve09.f90 (+4-4)
``````````diff
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 6d872094811e3..c9cc02703fbc8 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -182,6 +182,13 @@ end
Note that internally the main program symbol name is all uppercase, unlike
the names of all other symbols, which are usually all lowercase. This
may make a difference in testing/debugging.
+* A `PROCEDURE()` with no interface name or type may be called as an
+ subroutine with an implicit interface, F'2023 15.4.3.6 paragraph 4 and
+ C1525 notwithstanding.
+ This is a universally portable feature, and it also applies to
+ `PROCEDURE(), POINTER, NOPASS` derived type components.
+ Such procedures may *not* be referenced as implicitly typed functions
+ without first being associated with a function pointer.
## Extensions, deletions, and legacy features supported by default
@@ -954,4 +961,3 @@ print *, [(j,j=1,10)]
"&GRP A(1:)=1. 2. 3./".
This extension is necessarily disabled when the type of the array
has an accessible defined formatted READ subroutine.
-
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 0e6d4c71b30de..cb9dd792d0ad3 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -9435,13 +9435,18 @@ bool ResolveNamesVisitor::SetProcFlag(
SayWithDecl(name, symbol,
"Implicit declaration of function '%s' has a different result type than in previous declaration"_err_en_US);
return false;
- } else if (symbol.has<ProcEntityDetails>()) {
- symbol.set(flag); // in case it hasn't been set yet
- if (flag == Symbol::Flag::Function) {
- ApplyImplicitRules(symbol);
- }
- if (symbol.attrs().test(Attr::INTRINSIC)) {
- AcquireIntrinsicProcedureFlags(symbol);
+ } else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}) {
+ if (IsPointer(symbol) && !proc->type() && !proc->procInterface()) {
+ // PROCEDURE(), POINTER -- errors will be emitted later about a lack
+ // of known characteristics if used as a function
+ } else {
+ symbol.set(flag); // in case it hasn't been set yet
+ if (flag == Symbol::Flag::Function) {
+ ApplyImplicitRules(symbol);
+ }
+ if (symbol.attrs().test(Attr::INTRINSIC)) {
+ AcquireIntrinsicProcedureFlags(symbol);
+ }
}
} else if (symbol.GetType() && flag == Symbol::Flag::Subroutine) {
SayWithDecl(
diff --git a/flang/test/Semantics/resolve09.f90 b/flang/test/Semantics/resolve09.f90
index 2fe21aebf66bd..3384b05bf8f27 100644
--- a/flang/test/Semantics/resolve09.f90
+++ b/flang/test/Semantics/resolve09.f90
@@ -140,11 +140,11 @@ subroutine s9
procedure(), nopass, pointer :: p1, p2
end type
type(t) x
+ !ERROR: Function result characteristics are not known
print *, x%p1()
- call x%p2
- !ERROR: Cannot call function 'p1' like a subroutine
- call x%p1
- !ERROR: Cannot call subroutine 'p2' like a function
+ call x%p2 ! ok
+ call x%p1 ! ok
+ !ERROR: Function result characteristics are not known
print *, x%p2()
end subroutine
``````````
</details>
https://github.com/llvm/llvm-project/pull/165786
More information about the flang-commits
mailing list