[flang-commits] [flang] [flang] Fix edge case regression (PR #109350)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Sep 19 16:23:12 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/109350

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.

>From d9a23790a5a3ef54507d09c4f308cebf15bb87dd Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Thu, 19 Sep 2024 16:19:57 -0700
Subject: [PATCH] [flang] Fix edge case regression

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.
---
 flang/lib/Semantics/mod-file.cpp      |  4 +--
 flang/lib/Semantics/resolve-names.cpp | 14 ++++++---
 flang/test/Semantics/modfile69.f90    | 44 +++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 7 deletions(-)
 create mode 100644 flang/test/Semantics/modfile69.f90

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



More information about the flang-commits mailing list