[flang] Better handling of merged generics

If a generic name is use-associated from two different modules and they
both have a specific procedure or both have a derived type with the same
name, report it as an error.

Original-commit: flang-compiler/f18@42369af96d
Reviewed-on: https://github.com/flang-compiler/f18/pull/741
Tree-same-pre-rewrite: false
This commit is contained in:
Tim Keith 2019-09-13 14:27:33 -07:00
parent d43405e4e6
commit f13cf9f0ed
2 changed files with 37 additions and 5 deletions

View File

@ -2023,12 +2023,29 @@ void ModuleVisitor::AddUse(
useSymbol.has<GenericDetails>()) { useSymbol.has<GenericDetails>()) {
// use-associating generics with the same names: merge them into a // use-associating generics with the same names: merge them into a
// new generic in this scope // new generic in this scope
auto genericDetails{ultimate.get<GenericDetails>()}; auto generic1{ultimate.get<GenericDetails>()};
genericDetails.set_useDetails(*useDetails); generic1.set_useDetails(*useDetails);
genericDetails.CopyFrom(useSymbol.get<GenericDetails>()); // useSymbol has specific g and so does generic1
auto &generic2{useSymbol.get<GenericDetails>()};
if (generic1.specific() && generic2.specific() &&
generic1.specific() != generic2.specific()) {
Say(location,
"Generic interface '%s' has ambiguous specific procedures"
" from modules '%s' and '%s'"_err_en_US,
localSymbol.name(), useDetails->module().name(),
useSymbol.owner().GetName().value());
} else if (generic1.derivedType() && generic2.derivedType() &&
generic1.derivedType() != generic2.derivedType()) {
Say(location,
"Generic interface '%s' has ambiguous derived types"
" from modules '%s' and '%s'"_err_en_US,
localSymbol.name(), useDetails->module().name(),
useSymbol.owner().GetName().value());
} else {
generic1.CopyFrom(generic2);
}
EraseSymbol(localSymbol); EraseSymbol(localSymbol);
MakeSymbol( MakeSymbol(localSymbol.name(), ultimate.attrs(), std::move(generic1));
localSymbol.name(), ultimate.attrs(), std::move(genericDetails));
} else { } else {
ConvertToUseError(localSymbol, location, *useModuleScope_); ConvertToUseError(localSymbol, location, *useModuleScope_);
} }

View File

@ -198,8 +198,23 @@ contains
real :: x real :: x
end end
end module end module
module m9c
interface g
module procedure g
end interface
contains
subroutine g(x)
real :: x
end
end module
! Merge use-associated generics that have the same symbol (s1) ! Merge use-associated generics that have the same symbol (s1)
subroutine s9 subroutine s9
use m9a use m9a
use m9b use m9b
end end
! Merge use-associate generics each with specific of same name
subroutine s9c
use m9a
!ERROR: Generic interface 'g' has ambiguous specific procedures from modules 'm9a' and 'm9c'
use m9c
end