[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