Skip to content

Commit 2abcb19

Browse files
authored
[flang] Don't allow function calls to PROCEDURE() (#165786)
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.
1 parent 5354681 commit 2abcb19

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

flang/docs/Extensions.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ end
182182
Note that internally the main program symbol name is all uppercase, unlike
183183
the names of all other symbols, which are usually all lowercase. This
184184
may make a difference in testing/debugging.
185+
* A `PROCEDURE()` with no interface name or type may be called as an
186+
subroutine with an implicit interface, F'2023 15.4.3.6 paragraph 4 and
187+
C1525 notwithstanding.
188+
This is a universally portable feature, and it also applies to
189+
`PROCEDURE(), POINTER, NOPASS` derived type components.
190+
Such procedures may *not* be referenced as implicitly typed functions
191+
without first being associated with a function pointer.
185192

186193
## Extensions, deletions, and legacy features supported by default
187194

@@ -954,4 +961,3 @@ print *, [(j,j=1,10)]
954961
"&GRP A(1:)=1. 2. 3./".
955962
This extension is necessarily disabled when the type of the array
956963
has an accessible defined formatted READ subroutine.
957-

flang/lib/Semantics/resolve-names.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9435,13 +9435,18 @@ bool ResolveNamesVisitor::SetProcFlag(
94359435
SayWithDecl(name, symbol,
94369436
"Implicit declaration of function '%s' has a different result type than in previous declaration"_err_en_US);
94379437
return false;
9438-
} else if (symbol.has<ProcEntityDetails>()) {
9439-
symbol.set(flag); // in case it hasn't been set yet
9440-
if (flag == Symbol::Flag::Function) {
9441-
ApplyImplicitRules(symbol);
9442-
}
9443-
if (symbol.attrs().test(Attr::INTRINSIC)) {
9444-
AcquireIntrinsicProcedureFlags(symbol);
9438+
} else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}) {
9439+
if (IsPointer(symbol) && !proc->type() && !proc->procInterface()) {
9440+
// PROCEDURE(), POINTER -- errors will be emitted later about a lack
9441+
// of known characteristics if used as a function
9442+
} else {
9443+
symbol.set(flag); // in case it hasn't been set yet
9444+
if (flag == Symbol::Flag::Function) {
9445+
ApplyImplicitRules(symbol);
9446+
}
9447+
if (symbol.attrs().test(Attr::INTRINSIC)) {
9448+
AcquireIntrinsicProcedureFlags(symbol);
9449+
}
94459450
}
94469451
} else if (symbol.GetType() && flag == Symbol::Flag::Subroutine) {
94479452
SayWithDecl(

flang/test/Semantics/resolve09.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ subroutine s9
140140
procedure(), nopass, pointer :: p1, p2
141141
end type
142142
type(t) x
143+
!ERROR: Function result characteristics are not known
143144
print *, x%p1()
144-
call x%p2
145-
!ERROR: Cannot call function 'p1' like a subroutine
146-
call x%p1
147-
!ERROR: Cannot call subroutine 'p2' like a function
145+
call x%p2 ! ok
146+
call x%p1 ! ok
147+
!ERROR: Function result characteristics are not known
148148
print *, x%p2()
149149
end subroutine
150150

0 commit comments

Comments
 (0)