Skip to content

Commit a256c93

Browse files
klauslerjeanPerier
authored andcommitted
[flang] Enforce specification function rules on callee, not call
A function can't be a specification function if it has a dummy procedure argument, even if it's optional and unused. So don't check the reference for actual procedure arguments, but rather the characteristics of the function. Differential Revision: https://reviews.llvm.org/D109935
1 parent 1b142d9 commit a256c93

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

flang/lib/Evaluate/check-expression.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,6 @@ class CheckSpecificationExprHelper
460460
: Base{*this}, scope_{s}, context_{context} {}
461461
using Base::operator();
462462

463-
Result operator()(const ProcedureDesignator &) const {
464-
return "dummy procedure argument";
465-
}
466463
Result operator()(const CoarrayRef &) const { return "coindexed reference"; }
467464

468465
Result operator()(const semantics::Symbol &symbol) const {
@@ -541,6 +538,20 @@ class CheckSpecificationExprHelper
541538
"' not allowed for derived type components or type parameter"
542539
" values";
543540
}
541+
if (auto procChars{
542+
characteristics::Procedure::Characterize(x.proc(), context_)}) {
543+
const auto iter{std::find_if(procChars->dummyArguments.begin(),
544+
procChars->dummyArguments.end(),
545+
[](const characteristics::DummyArgument &dummy) {
546+
return std::holds_alternative<characteristics::DummyProcedure>(
547+
dummy.u);
548+
})};
549+
if (iter != procChars->dummyArguments.end()) {
550+
return "reference to function '"s + ultimate.name().ToString() +
551+
"' with dummy procedure argument '" + iter->name + '\'';
552+
}
553+
}
554+
// References to internal functions are caught in expression semantics.
544555
// TODO: other checks for standard module procedures
545556
} else {
546557
const SpecificIntrinsic &intrin{DEREF(x.proc().GetSpecificIntrinsic())};

flang/test/Semantics/expr-errors02.f90

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pure real function realfunc(x)
1515
pure integer function hasProcArg(p)
1616
import realfunc
1717
procedure(realfunc) :: p
18+
optional :: p
1819
end function
1920
end interface
2021
integer :: coarray[*]
@@ -37,8 +38,8 @@ subroutine test(out, optional)
3738
integer, intent(in), optional :: optional
3839
!ERROR: Invalid specification expression: reference to OPTIONAL dummy argument 'optional'
3940
type(t(optional)) :: x5
40-
!ERROR: Invalid specification expression: dummy procedure argument
41-
type(t(hasProcArg(realfunc))) :: x6
41+
!ERROR: Invalid specification expression: reference to function 'hasprocarg' with dummy procedure argument 'p'
42+
type(t(hasProcArg())) :: x6
4243
!ERROR: Invalid specification expression: coindexed reference
4344
type(t(coarray[1])) :: x7
4445
type(t(kind(foo()))) :: x101 ! ok

0 commit comments

Comments
 (0)