[flang] Ensure USE associations of shadowed procedures are emitted to module files

When a generic interface in a module shadows a procedure of the same name that
has been brought into scope via USE association, ensure that that USE association is
not lost when the module file is written.

Differential Revision: https://reviews.llvm.org/D135207
This commit is contained in:
Peter Klausler 2022-09-26 16:24:32 -07:00
parent de457f6489
commit 3411263dde
2 changed files with 63 additions and 4 deletions

View File

@ -2829,7 +2829,7 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
} else {
return;
}
} else if (&useUltimate == &BypassGeneric(localUltimate)) {
} else if (&useUltimate == &BypassGeneric(localUltimate).GetUltimate()) {
return; // nothing to do; used subprogram is local's specific
}
} else if (useGeneric) {
@ -3230,7 +3230,7 @@ void InterfaceVisitor::CheckGenericProcedures(Symbol &generic) {
SayDerivedType(generic.name(),
"Generic interface '%s' may only contain functions due to derived type"
" with same name"_err_en_US,
*details.derivedType()->scope());
*details.derivedType()->GetUltimate().scope());
}
generic.set(isFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
}
@ -7259,9 +7259,9 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
}
} else if (ultimate.has<SubprogramDetails>() ||
ultimate.has<SubprogramNameDetails>()) {
genericDetails.set_specific(ultimate);
genericDetails.set_specific(*existing);
} else if (ultimate.has<DerivedTypeDetails>()) {
genericDetails.set_derivedType(ultimate);
genericDetails.set_derivedType(*existing);
} else {
SayAlreadyDeclared(symbolName, *existing);
return;

View File

@ -0,0 +1,59 @@
! RUN: %python %S/test_modfile.py %s %flang_fc1
! Ensure that procedure name or derived type name that has been shadowed
! behind a generic interface gets its proper USE statement in a module file.
module m1
contains
subroutine foo
end subroutine
end module
module m2
use m1
interface foo
procedure foo
end interface
end module
module m3
type foo
end type
end module
module m4
use m4
interface foo
procedure bar
end interface
contains
integer function bar
end function
end module
!Expect: m1.mod
!module m1
!contains
!subroutine foo()
!end
!end
!Expect: m2.mod
!module m2
!use m1,only:foo
!interface foo
!procedure::foo
!end interface
!end
!Expect: m3.mod
!module m3
!type::foo
!end type
!end
!Expect: m4.mod
!module m4
!interface foo
!procedure::bar
!end interface
!contains
!function bar()
!integer(4)::bar
!end
!end