aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flang/lib/Semantics/mod-file.cpp5
-rw-r--r--flang/lib/Semantics/resolve-names.cpp24
-rw-r--r--flang/test/Semantics/resolve17.f902
3 files changed, 28 insertions, 3 deletions
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 50ea580..0be0e96 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 2c94f57..9cd3a41 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 b2c6d0e..76b9cbe 100644
--- a/flang/test/Semantics/resolve17.f90
+++ b/flang/test/Semantics/resolve17.f90
@@ -190,11 +190,13 @@ contains
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