[flang-commits] [flang] [flang] Fix edge case regression (PR #109350)
via flang-commits
flang-commits at lists.llvm.org
Thu Sep 19 16:23:45 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/109350.diff
3 Files Affected:
- (modified) flang/lib/Semantics/mod-file.cpp (+2-2)
- (modified) flang/lib/Semantics/resolve-names.cpp (+9-5)
- (added) flang/test/Semantics/modfile69.f90 (+44)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/109350
More information about the flang-commits
mailing list