forked from OSchip/llvm-project
[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:
parent
d43405e4e6
commit
f13cf9f0ed
|
@ -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_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue