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 @@ -2603,36 +2603,43 @@ Say(*name, "Procedure '%s' not found"_err_en_US); continue; } - symbol = &symbol->GetUltimate(); if (symbol == &generic) { if (auto *specific{generic.get().specific()}) { symbol = specific; } } - if (!symbol->has() && - !symbol->has()) { + const Symbol &ultimate{symbol->GetUltimate()}; + if (!ultimate.has() && + !ultimate.has()) { Say(*name, "'%s' is not a subprogram"_err_en_US); continue; } if (kind == ProcedureKind::ModuleProcedure) { - if (const auto *nd{symbol->detailsIf()}) { + if (const auto *nd{ultimate.detailsIf()}) { if (nd->kind() != SubprogramKind::Module) { Say(*name, "'%s' is not a module procedure"_err_en_US); } } else { // USE-associated procedure - const auto *sd{symbol->detailsIf()}; + const auto *sd{ultimate.detailsIf()}; CHECK(sd); - if (symbol->owner().kind() != Scope::Kind::Module || + if (ultimate.owner().kind() != Scope::Kind::Module || sd->isInterface()) { Say(*name, "'%s' is not a module procedure"_err_en_US); } } } - if (!symbolsSeen.insert(*symbol).second) { - Say(name->source, - "Procedure '%s' is already specified in generic '%s'"_err_en_US, - name->source, MakeOpName(generic.name())); + if (!symbolsSeen.insert(ultimate).second) { + if (symbol == &ultimate) { + Say(name->source, + "Procedure '%s' is already specified in generic '%s'"_err_en_US, + name->source, MakeOpName(generic.name())); + } else { + Say(name->source, + "Procedure '%s' from module '%s' is already specified in generic '%s'"_err_en_US, + ultimate.name(), ultimate.owner().GetName().value(), + MakeOpName(generic.name())); + } continue; } details.AddSpecificProc(*symbol, name->source); diff --git a/flang/test/Semantics/modfile07.f90 b/flang/test/Semantics/modfile07.f90 --- a/flang/test/Semantics/modfile07.f90 +++ b/flang/test/Semantics/modfile07.f90 @@ -598,3 +598,29 @@ ! end interface ! private::operator(.ne.) !end + +module m11a +contains + subroutine s1() + end +end +!Expect: m11a.mod +!module m11a +!contains +! subroutine s1() +! end +!end + +module m11b + use m11a + interface g + module procedure s1 + end interface +end +!Expect: m11b.mod +!module m11b +! use m11a,only:s1 +! interface g +! procedure::s1 +! end interface +!end diff --git a/flang/test/Semantics/resolve53.f90 b/flang/test/Semantics/resolve53.f90 --- a/flang/test/Semantics/resolve53.f90 +++ b/flang/test/Semantics/resolve53.f90 @@ -471,11 +471,11 @@ subroutine s1() use m20 interface operator(.not.) - !ERROR: Procedure 'f' is already specified in generic 'OPERATOR(.NOT.)' + !ERROR: Procedure 'f' from module 'm20' is already specified in generic 'OPERATOR(.NOT.)' procedure f end interface interface operator(+) - !ERROR: Procedure 'f' is already specified in generic 'OPERATOR(+)' + !ERROR: Procedure 'f' from module 'm20' is already specified in generic 'OPERATOR(+)' procedure f end interface end subroutine s1