diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -745,7 +745,7 @@ } funcInfo_; // Create a subprogram symbol in the current scope and push a new scope. - void CheckExtantExternal(const parser::Name &, Symbol::Flag); + void CheckExtantProc(const parser::Name &, Symbol::Flag); Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag); Symbol *GetSpecificFromGeneric(const parser::Name &); SubprogramDetails &PostSubprogramStmt(const parser::Name &); @@ -3084,7 +3084,6 @@ Symbol::Flag subpFlag{ inFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine}; - CheckExtantExternal(name, subpFlag); Scope &outer{inclusiveScope.parent()}; // global or module scope if (Symbol * extant{FindSymbol(outer, name)}) { if (extant->has()) { @@ -3176,7 +3175,7 @@ void SubprogramVisitor::EndSubprogram() { PopScope(); } -void SubprogramVisitor::CheckExtantExternal( +void SubprogramVisitor::CheckExtantProc( const parser::Name &name, Symbol::Flag subpFlag) { if (auto *prev{FindSymbol(name)}) { if (prev->attrs().test(Attr::EXTERNAL) && prev->has()) { @@ -3189,6 +3188,11 @@ *prev, "Previous call of '%s'"_en_US); } EraseSymbol(name); + } else if (const auto *details{prev->detailsIf()}) { + if (!details->isDummy()) { + Say2(name, "Procedure '%s' was previously declared"_err_en_US, *prev, + "Previous declaration of '%s'"_en_US); + } } } } @@ -3197,7 +3201,7 @@ const parser::Name &name, Symbol::Flag subpFlag) { auto *symbol{GetSpecificFromGeneric(name)}; if (!symbol) { - CheckExtantExternal(name, subpFlag); + CheckExtantProc(name, subpFlag); symbol = &MakeSymbol(name, SubprogramDetails{}); } symbol->set(subpFlag); diff --git a/flang/test/Semantics/resolve18.f90 b/flang/test/Semantics/resolve18.f90 --- a/flang/test/Semantics/resolve18.f90 +++ b/flang/test/Semantics/resolve18.f90 @@ -94,3 +94,30 @@ use m5b type(g) :: y end + +module m6 + real :: f6 + interface g6 + !ERROR: Procedure 'f6' was previously declared + real function f6() + end function f6 + end interface g6 +end module m6 + +module m7 + integer :: f7 + interface g7 + !ERROR: Procedure 'f7' was previously declared + real function f7() + end function f7 + end interface g7 +end module m7 + +module m8 + real :: f8 + interface g8 + !ERROR: Procedure 'f8' was previously declared + subroutine f8() + end subroutine f8 + end interface g8 +end module m8