-
Notifications
You must be signed in to change notification settings - Fork 11.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[flang] Fix edge case regression #109350
base: main
Are you sure you want to change the base?
[flang] Fix edge case regression #109350
Conversation
A recent fix to the emission of derived type names to module files exposed a regression in the case of a derived type that (1) has the same name as a generic procedure interface and (2) has undergone renaming through USE association before (3) being used in a declaration significant to a module procedure interface. Fix.
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesA recent fix to the emission of derived type names to module files exposed a regression in the case of a derived type that (1) has the same name as a generic procedure interface and (2) has undergone renaming through USE association before (3) being used in a declaration significant to a module procedure interface. Fix. Full diff: https://github.com/llvm/llvm-project/pull/109350.diff 3 Files Affected:
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index c7e7716a7b4816..52a5a321aba646 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -1626,8 +1626,8 @@ void SubprogramSymbolCollector::Collect() {
// &/or derived type that it shadows may be needed.
const Symbol *spec{generic->specific()};
const Symbol *dt{generic->derivedType()};
- needed = needed || (spec && useSet_.count(*spec) > 0) ||
- (dt && useSet_.count(*dt) > 0);
+ needed = needed || (spec && useSet_.count(spec->GetUltimate()) > 0) ||
+ (dt && useSet_.count(dt->GetUltimate()) > 0);
} else if (const auto *subp{ultimate.detailsIf<SubprogramDetails>()}) {
const Symbol *interface { subp->moduleInterface() };
needed = needed || (interface && useSet_.count(*interface) > 0);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5414787d85f7f7..1e9a479836c429 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3059,10 +3059,10 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
(useGeneric->derivedType() &&
useUltimate.name() != localSymbol->name()))) {
// We are use-associating a generic that either shadows a procedure
- // pointer or shadows a derived type of the same name.
+ // pointer or shadows a derived type with a distinct name.
// Local references that might be made to the procedure pointer should
// use a UseDetails symbol for proper data addressing, and a derived
- // type needs to be in scope with the renamed name. So create an
+ // type needs to be in scope with its local name. So create an
// empty local generic now into which the use-associated generic may
// be copied.
localSymbol->set_details(GenericDetails{});
@@ -3143,6 +3143,7 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
// scope's name map.
auto CreateLocalUseError{[&]() {
EraseSymbol(*localSymbol);
+ CHECK(localSymbol->has<UseDetails>());
UseErrorDetails details{localSymbol->get<UseDetails>()};
details.add_occurrence(location, *useModuleScope_);
Symbol *newSymbol{&MakeSymbol(localName, Attrs{}, std::move(details))};
@@ -3161,10 +3162,13 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
if (useDerivedType->name() == localName) {
combinedDerivedType = useDerivedType;
} else {
- Symbol &combined{currScope().MakeSymbol(localName,
- useDerivedType->attrs(), UseDetails{localName, *useDerivedType})};
- combinedDerivedType = &combined;
+ combinedDerivedType =
+ &currScope().MakeSymbol(localSymbol->name(), useDerivedType->attrs(),
+ UseDetails{localSymbol->name(), *useDerivedType});
}
+ } else if (&localDerivedType->GetUltimate() ==
+ &useDerivedType->GetUltimate()) {
+ combinedDerivedType = localDerivedType;
} else {
const Scope *localScope{localDerivedType->GetUltimate().scope()};
const Scope *useScope{useDerivedType->GetUltimate().scope()};
diff --git a/flang/test/Semantics/modfile69.f90 b/flang/test/Semantics/modfile69.f90
new file mode 100644
index 00000000000000..6586e0524f5eaa
--- /dev/null
+++ b/flang/test/Semantics/modfile69.f90
@@ -0,0 +1,44 @@
+! RUN: %python %S/test_modfile.py %s %flang_fc1
+module m1
+ type foo
+ end type
+ interface foo
+ end interface
+end
+
+!Expect: m1.mod
+!module m1
+!type::foo
+!end type
+!interface foo
+!end interface
+!end
+
+module m2
+ use m1, only: bar => foo
+end
+
+!Expect: m2.mod
+!module m2
+!use m1,only:bar=>foo
+!use m1,only:bar=>foo
+!interface bar
+!end interface
+!end
+
+module m3
+ contains
+ subroutine sub(x)
+ use m2
+ type(bar) x
+ end
+end
+
+!Expect: m3.mod
+!module m3
+!contains
+!subroutine sub(x)
+!use m2,only:bar
+!type(bar)::x
+!end
+!end
|
A recent fix to the emission of derived type names to module files exposed a regression in the case of a derived type that (1) has the same name as a generic procedure interface and (2) has undergone renaming through USE association before (3) being used in a declaration significant to a module procedure interface. Fix.