[flang-commits] [flang] 37a0022 - [flang] Don't lose homonymous specific when copying generic
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Tue Aug 9 07:56:29 PDT 2022
Author: Peter Klausler
Date: 2022-08-09T07:44:52-07:00
New Revision: 37a0022aaa5a2ab15d7933e1c84e30b53a895bca
URL: https://github.com/llvm/llvm-project/commit/37a0022aaa5a2ab15d7933e1c84e30b53a895bca
DIFF: https://github.com/llvm/llvm-project/commit/37a0022aaa5a2ab15d7933e1c84e30b53a895bca.diff
LOG: [flang] Don't lose homonymous specific when copying generic
Defined generic procedure interfaces are allowed to shadow non-generic
procedures of the same name in the same scope (whether or not
that non-generic procedure is a specific procedure of the generic).
When making a copy of a generic interface symbol so that it can
be locally modified or be merged with another generic, don't forget
about the homonymous non-generic procedure that it might shadow.
Differential Revision: https://reviews.llvm.org/D131103
Added:
Modified:
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/resolve17.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 50ea58077c419..0be0e961f3498 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -273,10 +273,11 @@ void ModFileWriter::PutSymbol(
}
} else {
PutGeneric(symbol);
- if (x.specific()) {
+ if (x.specific() && &x.specific()->owner() == &symbol.owner()) {
PutSymbol(typeBindings, *x.specific());
}
- if (x.derivedType()) {
+ if (x.derivedType() &&
+ &x.derivedType()->owner() == &symbol.owner()) {
PutSymbol(typeBindings, *x.derivedType());
}
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 2c94f57a502eb..9cd3a414ed538 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2859,6 +2859,9 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
// it can be locally extended without corrupting the original.
GenericDetails generic;
generic.CopyFrom(*localGeneric);
+ if (localGeneric->specific()) {
+ generic.set_specific(*localGeneric->specific());
+ }
EraseSymbol(localSymbol);
Symbol &newSymbol{MakeSymbol(
localSymbol.name(), localSymbol.attrs(), std::move(generic))};
@@ -2873,6 +2876,19 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
localSymbol.flags() = useSymbol.flags();
AddGenericUse(*localGeneric, localName, useUltimate);
localGeneric->CopyFrom(*useGeneric);
+ if (useGeneric->specific()) {
+ if (!localGeneric->specific()) {
+ localGeneric->set_specific(
+ *const_cast<Symbol *>(useGeneric->specific()));
+ } else if (&localGeneric->specific()->GetUltimate() !=
+ &useGeneric->specific()->GetUltimate()) {
+ Say(location,
+ "Cannot use-associate generic interface '%s' with specific procedure of the same name when another such generic is in scope"_err_en_US,
+ localName)
+ .Attach(
+ localSymbol.name(), "Previous USE of '%s'"_en_US, localName);
+ }
+ }
} else {
CHECK(useUltimate.has<DerivedTypeDetails>());
localGeneric->set_derivedType(
@@ -2885,6 +2901,9 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
// with the local derived type.
GenericDetails generic;
generic.CopyFrom(*useGeneric);
+ if (useGeneric->specific()) {
+ generic.set_specific(*const_cast<Symbol *>(useGeneric->specific()));
+ }
EraseSymbol(localSymbol);
Symbol &newSymbol{MakeSymbol(localName,
useUltimate.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE},
@@ -7134,11 +7153,14 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
}
if (existing) {
Symbol &ultimate{existing->GetUltimate()};
- if (const auto *existingGeneric{ultimate.detailsIf<GenericDetails>()}) {
+ if (auto *existingGeneric{ultimate.detailsIf<GenericDetails>()}) {
if (const auto *existingUse{existing->detailsIf<UseDetails>()}) {
// Create a local copy of a use associated generic so that
// it can be locally extended without corrupting the original.
genericDetails.CopyFrom(*existingGeneric);
+ if (existingGeneric->specific()) {
+ genericDetails.set_specific(*existingGeneric->specific());
+ }
AddGenericUse(genericDetails, existing->name(), existingUse->symbol());
} else if (existing == &ultimate) {
// Extending an extant generic in the same scope
diff --git a/flang/test/Semantics/resolve17.f90 b/flang/test/Semantics/resolve17.f90
index b2c6d0e26eeea..76b9cbed1d62f 100644
--- a/flang/test/Semantics/resolve17.f90
+++ b/flang/test/Semantics/resolve17.f90
@@ -190,11 +190,13 @@ subroutine g()
end module
subroutine s9a
use m9a
+ !ERROR: Cannot use-associate generic interface 'g' with specific procedure of the same name when another such generic is in scope
use m9b
end
subroutine s9b
!ERROR: USE-associated generic 'g' may not have specific procedures 'g' and 'g' as their interfaces are not distinguishable
use m9a
+ !ERROR: Cannot use-associate generic interface 'g' with specific procedure of the same name when another such generic is in scope
use m9c
end
More information about the flang-commits
mailing list