[flang-commits] [flang] ce8effc - [flang] Fix USE with homonymous renaming

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Jun 22 07:35:17 PDT 2023


Author: Peter Klausler
Date: 2023-06-22T07:35:12-07:00
New Revision: ce8effc88aafa406d5fa5894abfa6fe9860b9c79

URL: https://github.com/llvm/llvm-project/commit/ce8effc88aafa406d5fa5894abfa6fe9860b9c79
DIFF: https://github.com/llvm/llvm-project/commit/ce8effc88aafa406d5fa5894abfa6fe9860b9c79.diff

LOG: [flang] Fix USE with homonymous renaming

Fortran requires that a USE with renaming prevent the USE'd symbol
from also being associated into a scope without renaming.  The
implementation in name resolution gets confused in the case of
a USE with renaming using the same name ("x => x").  Clean things
up.  Fixes LLVM bug https://github.com/llvm/llvm-project/issues/63397.

Differential Revision: https://reviews.llvm.org/D153452

Added: 
    

Modified: 
    flang/lib/Semantics/resolve-names.cpp
    flang/test/Semantics/modfile41.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index b9470c8386e1c..f7e6fb6fab40f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -789,8 +789,8 @@ class ModuleVisitor : public virtual ScopeHandler {
       SourceName, SourceName, Symbol &localSymbol, const Symbol &useSymbol);
   void AddUse(const GenericSpecInfo &);
   // If appropriate, erase a previously USE-associated symbol
-  void EraseRenamedSymbol(const Symbol &);
-  // Record a name appearing in a USE rename clause
+  void EraseRenamedUse(const Symbol *);
+  // Record a name appearing as the target of a USE rename clause
   void AddUseRename(const SourceName &name) {
     useRenames_.emplace(std::make_pair(name, useModuleScope_));
   }
@@ -2775,11 +2775,8 @@ bool ModuleVisitor::Pre(const parser::Only &x) {
 bool ModuleVisitor::Pre(const parser::Rename::Names &x) {
   const auto &localName{std::get<0>(x.t)};
   const auto &useName{std::get<1>(x.t)};
-  AddUseRename(useName.source);
   SymbolRename rename{AddUse(localName.source, useName.source)};
-  if (rename.use && localName.source != useName.source) {
-    EraseRenamedSymbol(*rename.use);
-  }
+  AddUseRename(useName.source);
   Resolve(useName, rename.use);
   Resolve(localName, rename.local);
   return false;
@@ -2797,9 +2794,6 @@ bool ModuleVisitor::Pre(const parser::Rename::Operators &x) {
         "Logical constant '%s' may not be used as a defined operator"_err_en_US);
   } else {
     SymbolRename rename{AddUse(localInfo.symbolName(), useInfo.symbolName())};
-    if (rename.use) {
-      EraseRenamedSymbol(*rename.use);
-    }
     useInfo.Resolve(rename.use);
     localInfo.Resolve(rename.local);
   }
@@ -2910,17 +2904,20 @@ static bool ConvertToUseError(
   }
 }
 
-// If a symbol has previously been USE-associated and did not appear in a USE
-// ONLY clause, erase it from the current scope.  This is needed when a name
-// appears in a USE rename clause.
-void ModuleVisitor::EraseRenamedSymbol(const Symbol &useSymbol) {
-  const SourceName &name{useSymbol.name()};
+// If a symbol has previously been USE-associated and did not appear in
+// an ONLY clause or renaming, erase it from the current scope.  This is
+// necessary when a name appears as the target of a later USE rename clause.
+void ModuleVisitor::EraseRenamedUse(const Symbol *useSymbol) {
+  if (!useSymbol) {
+    return;
+  }
+  const SourceName &name{useSymbol->name()};
   if (const Symbol * symbol{FindInScope(name)}) {
-    if (auto *useDetails{symbol->detailsIf<UseDetails>()}) {
+    if (const auto *useDetails{symbol->detailsIf<UseDetails>()}) {
       const Symbol &moduleSymbol{useDetails->symbol()};
       if (moduleSymbol.name() == name &&
-          moduleSymbol.owner() == useSymbol.owner() && IsUseRenamed(name) &&
-          !IsUseOnly(name)) {
+          moduleSymbol.owner() == useSymbol->owner() && !IsUseOnly(name) &&
+          !IsUseRenamed(name)) {
         EraseSymbol(*symbol);
       }
     }
@@ -2930,7 +2927,7 @@ void ModuleVisitor::EraseRenamedSymbol(const Symbol &useSymbol) {
 void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
     Symbol &localSymbol, const Symbol &useSymbol) {
   if (localName != useSymbol.name()) {
-    EraseRenamedSymbol(useSymbol);
+    EraseRenamedUse(&useSymbol);
   }
   if (auto *details{localSymbol.detailsIf<UseErrorDetails>()}) {
     details->add_occurrence(location, *useModuleScope_);

diff  --git a/flang/test/Semantics/modfile41.f90 b/flang/test/Semantics/modfile41.f90
index cc6c31490e80d..e1335a8f1de41 100644
--- a/flang/test/Semantics/modfile41.f90
+++ b/flang/test/Semantics/modfile41.f90
@@ -94,3 +94,9 @@ subroutine testUse12
   !ERROR: 'a' is use-associated from module 'm4' and cannot be re-declared
   integer :: a = 2
 end
+subroutine testUse13
+  use m1, a => a
+  use m1, z => a ! should not erase 'a', it was renamed
+  !ERROR: 'a' is use-associated from module 'm1' and cannot be re-declared
+  integer :: a = 13
+end


        


More information about the flang-commits mailing list