[flang-commits] [flang] [flang] Emit "raw" name for procedure interface in module file (PR #83915)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Mar 4 15:51:28 PST 2024


https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/83915

>From 6550615f62d42bfe6f57ba23a74778f2e4454c92 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 4 Mar 2024 13:51:20 -0800
Subject: [PATCH] [flang] Emit "raw" name for procedure interface in module
 file

Save both the raw procedure interface symbol as well as the result
of passing it through GetUltimate() and BypassGeneric() in symbol
table entries with ProcEntityDetails.  The raw symbol of the interface
needs to be the one used for emitting procedure symbols to module
files.

Fixes https://github.com/llvm/llvm-project/issues/83836.
---
 flang/include/flang/Semantics/symbol.h      |  7 ++++-
 flang/lib/Semantics/check-declarations.cpp  |  4 +--
 flang/lib/Semantics/mod-file.cpp            |  8 +++---
 flang/lib/Semantics/resolve-names-utils.cpp |  5 ++--
 flang/lib/Semantics/resolve-names.cpp       | 16 ++++++------
 flang/lib/Semantics/symbol.cpp              |  3 +++
 flang/lib/Semantics/tools.cpp               |  4 +--
 flang/test/Semantics/modfile64.f90          | 29 +++++++++++++++++++++
 8 files changed, 55 insertions(+), 21 deletions(-)
 create mode 100644 flang/test/Semantics/modfile64.f90

diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 125025dab5f448..c3175a5d1a111d 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -417,8 +417,12 @@ class ProcEntityDetails : public EntityDetails, public WithPassArg {
   ProcEntityDetails(ProcEntityDetails &&) = default;
   ProcEntityDetails &operator=(const ProcEntityDetails &) = default;
 
+  const Symbol *rawProcInterface() const { return rawProcInterface_; }
   const Symbol *procInterface() const { return procInterface_; }
-  void set_procInterface(const Symbol &sym) { procInterface_ = &sym; }
+  void set_procInterfaces(const Symbol &raw, const Symbol &resolved) {
+    rawProcInterface_ = &raw;
+    procInterface_ = &resolved;
+  }
   inline bool HasExplicitInterface() const;
 
   // Be advised: !init().has_value() => uninitialized pointer,
@@ -430,6 +434,7 @@ class ProcEntityDetails : public EntityDetails, public WithPassArg {
   void set_isCUDAKernel(bool yes = true) { isCUDAKernel_ = yes; }
 
 private:
+  const Symbol *rawProcInterface_{nullptr};
   const Symbol *procInterface_{nullptr};
   std::optional<const Symbol *> init_;
   bool isCUDAKernel_{false};
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 719bea34406aa0..e4449e24ad52aa 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1195,9 +1195,7 @@ void CheckHelper::CheckArraySpec(
 void CheckHelper::CheckProcEntity(
     const Symbol &symbol, const ProcEntityDetails &details) {
   CheckSymbolType(symbol);
-  const Symbol *interface {
-    details.procInterface() ? &details.procInterface()->GetUltimate() : nullptr
-  };
+  const Symbol *interface{details.procInterface()};
   if (details.isDummy()) {
     if (!symbol.attrs().test(Attr::POINTER) && // C843
         (symbol.attrs().test(Attr::INTENT_IN) ||
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 37fe0240537b8e..b4df7216a33e20 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -924,8 +924,8 @@ void ModFileWriter::PutProcEntity(llvm::raw_ostream &os, const Symbol &symbol) {
       os, symbol,
       [&]() {
         os << "procedure(";
-        if (details.procInterface()) {
-          os << details.procInterface()->name();
+        if (details.rawProcInterface()) {
+          os << details.rawProcInterface()->name();
         } else if (details.type()) {
           PutType(os, *details.type());
         }
@@ -1622,8 +1622,8 @@ void SubprogramSymbolCollector::DoSymbol(
                       }
                     },
                     [this](const ProcEntityDetails &details) {
-                      if (details.procInterface()) {
-                        DoSymbol(*details.procInterface());
+                      if (details.rawProcInterface()) {
+                        DoSymbol(*details.rawProcInterface());
                       } else {
                         DoType(details.type());
                       }
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index b901080e2860c4..801473876e7e2b 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -845,8 +845,9 @@ void SymbolMapper::MapSymbolExprs(Symbol &symbol) {
                        },
           [&](ProcEntityDetails &proc) {
             if (const Symbol *
-                mappedSymbol{MapInterface(proc.procInterface())}) {
-              proc.set_procInterface(*mappedSymbol);
+                mappedSymbol{MapInterface(proc.rawProcInterface())}) {
+              proc.set_procInterfaces(
+                  *mappedSymbol, BypassGeneric(mappedSymbol->GetUltimate()));
             } else if (const DeclTypeSpec * mappedType{MapType(proc.type())}) {
               proc.set_type(*mappedType);
             }
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5a95d3a98992a7..a88f639f94573a 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -4983,7 +4983,8 @@ Symbol &DeclarationVisitor::DeclareProcEntity(
           "The interface for procedure '%s' has already been declared"_err_en_US);
       context().SetError(symbol);
     } else if (interface) {
-      details->set_procInterface(*interface);
+      details->set_procInterfaces(
+          *interface, BypassGeneric(interface->GetUltimate()));
       if (interface->test(Symbol::Flag::Function)) {
         symbol.set(Symbol::Flag::Function);
       } else if (interface->test(Symbol::Flag::Subroutine)) {
@@ -5658,10 +5659,10 @@ void DeclarationVisitor::Post(const parser::ProcInterface &x) {
 }
 void DeclarationVisitor::Post(const parser::ProcDecl &x) {
   const auto &name{std::get<parser::Name>(x.t)};
-  const Symbol *procInterface{nullptr};
-  if (interfaceName_ && interfaceName_->symbol) {
-    procInterface = &BypassGeneric(*interfaceName_->symbol);
-  }
+  // Don't use BypassGeneric or GetUltimate on this symbol, they can
+  // lead to unusable names in module files.
+  const Symbol *procInterface{
+      interfaceName_ ? interfaceName_->symbol : nullptr};
   auto attrs{HandleSaveName(name.source, GetAttrs())};
   DerivedTypeDetails *dtDetails{nullptr};
   if (Symbol * symbol{currScope().symbol()}) {
@@ -6624,10 +6625,9 @@ void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
   if (const Symbol * symbol{name.symbol}) {
     const Symbol &ultimate{symbol->GetUltimate()};
     if (!context().HasError(*symbol) && !context().HasError(ultimate) &&
-        !ultimate.HasExplicitInterface()) {
+        !BypassGeneric(ultimate).HasExplicitInterface()) {
       Say(name,
-          "'%s' must be an abstract interface or a procedure with "
-          "an explicit interface"_err_en_US,
+          "'%s' must be an abstract interface or a procedure with an explicit interface"_err_en_US,
           symbol->name());
     }
   }
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 2ab3189cf4064e..381905b89fb2dd 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -452,6 +452,9 @@ llvm::raw_ostream &operator<<(
 llvm::raw_ostream &operator<<(
     llvm::raw_ostream &os, const ProcEntityDetails &x) {
   if (x.procInterface_) {
+    if (x.rawProcInterface_ != x.procInterface_) {
+      os << ' ' << x.rawProcInterface_->name() << " ->";
+    }
     os << ' ' << x.procInterface_->name();
   } else {
     DumpType(os, x.type());
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index f931ae07072010..bf999b090419c6 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -465,9 +465,7 @@ const Symbol *FindInterface(const Symbol &symbol) {
   return common::visit(
       common::visitors{
           [](const ProcEntityDetails &details) {
-            const Symbol *interface {
-              details.procInterface()
-            };
+            const Symbol *interface{details.procInterface()};
             return interface ? FindInterface(*interface) : nullptr;
           },
           [](const ProcBindingDetails &details) {
diff --git a/flang/test/Semantics/modfile64.f90 b/flang/test/Semantics/modfile64.f90
new file mode 100644
index 00000000000000..e9df005c9ffd31
--- /dev/null
+++ b/flang/test/Semantics/modfile64.f90
@@ -0,0 +1,29 @@
+! RUN: %python %S/test_modfile.py %s %flang_fc1
+module mod0
+  interface proc
+    module procedure proc
+  end interface
+ contains
+  subroutine proc
+  end
+end
+module mod1
+  use mod0,renamed_proc=>proc
+  procedure(renamed_proc),pointer :: p
+end module
+
+!Expect: mod0.mod
+!module mod0
+!interface proc
+!procedure::proc
+!end interface
+!contains
+!subroutine proc()
+!end
+!end
+
+!Expect: mod1.mod
+!module mod1
+!use mod0,only:renamed_proc=>proc
+!procedure(renamed_proc),pointer::p
+!end



More information about the flang-commits mailing list