diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1043,7 +1043,17 @@ for (const auto &pair : scope_) { const Symbol &symbol{*pair.second}; if (const auto *useDetails{symbol.detailsIf()}) { - if (useSet_.count(useDetails->symbol().GetUltimate()) > 0) { + const Symbol &ultimate{useDetails->symbol().GetUltimate()}; + bool needed{useSet_.count(ultimate) > 0}; + if (const auto *generic{ultimate.detailsIf()}) { + // The generic may not be needed itself, but the specific procedure + // &/or derived type that it shadows may be needed. + const Symbol *spec{generic->specific()}; + const Symbol *dt{generic->derivedType()}; + needed = needed || (spec && useSet_.count(*spec) > 0) || + (dt && useSet_.count(*dt) > 0); + } + if (needed) { need_.push_back(symbol); } } diff --git a/flang/test/Semantics/modfile44.f90 b/flang/test/Semantics/modfile44.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/modfile44.f90 @@ -0,0 +1,54 @@ +! RUN: %python %S/test_modfile.py %s %flang_fc1 +! Ensure that m2.mod explicitly USEs a generic interface from m1 +! so it can utilize its shadowed derived type. +module m1 + implicit none + type :: xyz + integer :: n + end type + interface xyz + module procedure xzy + end interface + contains + function xzy(j) result(res) + integer, intent(in) :: j + type(xyz) :: res + res%n = j + end function +end module + +!Expect: m1.mod +!module m1 +!interface xyz +!procedure::xzy +!end interface +!type::xyz +!integer(4)::n +!end type +!contains +!function xzy(j) result(res) +!integer(4),intent(in)::j +!type(xyz)::res +!end +!end + +module m2 + implicit none + contains + function foo(j) result(res) + use :: m1, only: xyz + integer, intent(in) :: j + type(xyz) :: res + res = xyz(j) + end function +end module + +!Expect: m2.mod +!module m2 +!contains +!function foo(j) result(res) +!use m1,only:xyz +!integer(4),intent(in)::j +!type(xyz)::res +!end +!end