[flang] Error message situation should be a warning

f18 emits an error message when the same name is used in a scope
for both a procedure and a generic interface, and the procedure is
not a specific procedure of the generic interface.  It may be
questionable usage, and not portable, but it does not appear to
be non-conforming by a strict reading of the standard, and many
popular Fortran compilers accept it.

Differential Revision: https://reviews.llvm.org/D135205
This commit is contained in:
Peter Klausler 2022-10-04 10:24:29 -07:00
parent 8100374437
commit de457f6489
4 changed files with 35 additions and 4 deletions

View File

@ -440,3 +440,34 @@ end subroutine
The precedent among the most commonly used compilers
agrees with f18's interpretation: a `DATA` statement without any other
specification of the name refers to the host-associated object.
* Many Fortran compilers allow a non-generic procedure to be `USE`-associated
into a scope that also contains a generic interface of the same name
but does not have the `USE`-associated non-generic procedure as a
specific procedure.
```
module m1
contains
subroutine foo(n)
integer, intent(in) :: n
end subroutine
end module
module m2
use m1, only: foo
interface foo
module procedure noargs
end interface
contains
subroutine noargs
end subroutine
end module
```
This case elicits a warning from f18, as it should not be treated
any differently than the same case with the non-generic procedure of
the same name being defined in the same scope rather than being
`USE`-associated into it, which is explicitly non-conforming in the
standard and not allowed by most other compilers.
If the `USE`-associated entity of the same name is not a procedure,
most compilers disallow it as well.

View File

@ -3196,8 +3196,8 @@ void InterfaceVisitor::CheckGenericProcedures(Symbol &generic) {
auto &details{generic.get<GenericDetails>()};
if (auto *proc{details.CheckSpecific()}) {
auto msg{
"'%s' may not be the name of both a generic interface and a"
" procedure unless it is a specific procedure of the generic"_err_en_US};
"'%s' should not be the name of both a generic interface and a"
" procedure unless it is a specific procedure of the generic"_warn_en_US};
if (proc->name().begin() > generic.name().begin()) {
Say(proc->name(), std::move(msg));
} else {

View File

@ -11,7 +11,7 @@ module m2
interface s
end interface
contains
!ERROR: 's' may not be the name of both a generic interface and a procedure unless it is a specific procedure of the generic
!WARNING: 's' should not be the name of both a generic interface and a procedure unless it is a specific procedure of the generic
subroutine s
end subroutine
end module

View File

@ -11,7 +11,7 @@ end module
module m2
use m1
implicit none
!ERROR: 'foo' may not be the name of both a generic interface and a procedure unless it is a specific procedure of the generic
!WARNING: 'foo' should not be the name of both a generic interface and a procedure unless it is a specific procedure of the generic
interface foo
module procedure s
end interface