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 @@ -3124,8 +3124,15 @@ Say(*name, "Procedure '%s' not found"_err_en_US); continue; } - const Symbol &specific{BypassGeneric(*symbol)}; - const Symbol &ultimate{specific.GetUltimate()}; + // Subtlety: when *symbol is a use- or host-association, the specific + // procedure that is recorded in the GenericDetails below must be *symbol, + // not the specific procedure shadowed by a generic, because that specific + // procedure may be a symbol from another module and its name unavailable to + // emit to a module file. + const Symbol &bypassed{BypassGeneric(*symbol)}; + const Symbol &specific{ + symbol == &symbol->GetUltimate() ? bypassed : *symbol}; + const Symbol &ultimate{bypassed.GetUltimate()}; if (!ultimate.has() && !ultimate.has()) { Say(*name, "'%s' is not a subprogram"_err_en_US); diff --git a/flang/test/Semantics/modfile50.f90 b/flang/test/Semantics/modfile50.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/modfile50.f90 @@ -0,0 +1,33 @@ +! RUN: %python %S/test_modfile.py %s %flang_fc1 +module m1 + interface foo + module procedure foo + end interface + contains + subroutine foo + end subroutine +end module +module m2 + use m1, bar => foo + interface baz + module procedure bar ! must not be replaced in module file with "foo" + end interface +end module + +!Expect: m1.mod +!module m1 +!interface foo +!procedure::foo +!end interface +!contains +!subroutine foo() +!end +!end + +!Expect: m2.mod +!module m2 +!use m1,only:bar=>foo +!interface baz +!procedure::bar +!end interface +!end