[flang-commits] [PATCH] D131103: [flang] Don't lose homonymous specific when copying generic
Peter Klausler via Phabricator via flang-commits
flang-commits at lists.llvm.org
Wed Aug 3 13:01:28 PDT 2022
klausler created this revision.
klausler added a reviewer: vdonaldson.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
klausler requested review of this revision.
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.
https://reviews.llvm.org/D131103
Files:
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/resolve17.f90
Index: flang/test/Semantics/resolve17.f90
===================================================================
--- flang/test/Semantics/resolve17.f90
+++ flang/test/Semantics/resolve17.f90
@@ -190,11 +190,13 @@
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
Index: flang/lib/Semantics/resolve-names.cpp
===================================================================
--- flang/lib/Semantics/resolve-names.cpp
+++ flang/lib/Semantics/resolve-names.cpp
@@ -2859,6 +2859,9 @@
// 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 @@
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 @@
// 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},
@@ -7125,11 +7144,14 @@
}
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
Index: flang/lib/Semantics/mod-file.cpp
===================================================================
--- flang/lib/Semantics/mod-file.cpp
+++ flang/lib/Semantics/mod-file.cpp
@@ -273,10 +273,11 @@
}
} 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());
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131103.449754.patch
Type: text/x-patch
Size: 4127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220803/9f1c81e8/attachment-0001.bin>
More information about the flang-commits
mailing list