[flang] Warn about violations of an obscure requirement (15.6.4 p2)

The Fortran 2018 standard, perhaps as an attempt to prevent ambiguity
in  older compilers, requires that a statement function appear in an
explicit type declaration statement if its name is also accessible
from a host scope.  F18 processes the specification parts of inner
procedures first, so we don't need this requirement to prevent
ambiguity, and can only really check it retrospectively after name
resolution.  Emit a portability warning when appropriate.

Differential Revision: https://reviews.llvm.org/D145100
This commit is contained in:
Peter Klausler 2023-02-17 16:48:25 -08:00
parent 2765fe8a61
commit 41b5f37185
3 changed files with 18 additions and 0 deletions

View File

@ -84,6 +84,10 @@ end
scope" -- i.e., not scoped by `BLOCK` constructs.
As most (but not all) compilers implement `BLOCK` scoping of construct
names, so does f18, with a portability warning.
* 15.6.4 paragraph 2 prohibits an implicitly typed statement function
from sharing the same name as a symbol in its scope's host, if it
has one.
We accept this usage with a portability warning.
## Extensions, deletions, and legacy features supported by default

View File

@ -1044,6 +1044,15 @@ void CheckHelper::CheckSubprogram(
if (auto msg{evaluate::CheckStatementFunction(
symbol, *stmtFunction, context_.foldingContext())}) {
SayWithDeclaration(symbol, std::move(*msg));
} else if (details.result().flags().test(Symbol::Flag::Implicit)) {
// 15.6.4 p2 weird requirement
if (const Symbol *
host{symbol.owner().parent().FindSymbol(symbol.name())}) {
evaluate::AttachDeclaration(
messages_.Say(symbol.name(),
"An implicitly typed statement function should not appear when the same symbol is available in its host scope"_port_en_US),
*host);
}
}
}
if (IsElementalProcedure(symbol)) {

View File

@ -34,6 +34,7 @@ program main
integer :: sf9
!ERROR: Defining expression of statement function 'sf9' cannot be converted to its result type INTEGER(4)
sf9(n) = "bad"
sf10 = 1.
contains
real function explicit(x,y)
integer, intent(in) :: x
@ -44,4 +45,8 @@ program main
real :: arr(2)
arr = [1., 2.]
end function
subroutine foo
!PORTABILITY: An implicitly typed statement function should not appear when the same symbol is available in its host scope
sf10(x) = 2.*x
end subroutine
end