Skip to content

Commit ce8effc

Browse files
committed
[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 llvm/llvm-project#63397. Differential Revision: https://reviews.llvm.org/D153452
1 parent 252d1c4 commit ce8effc

File tree

2 files changed

+21
-18
lines changed

2 files changed

+21
-18
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,8 @@ class ModuleVisitor : public virtual ScopeHandler {
789789
SourceName, SourceName, Symbol &localSymbol, const Symbol &useSymbol);
790790
void AddUse(const GenericSpecInfo &);
791791
// If appropriate, erase a previously USE-associated symbol
792-
void EraseRenamedSymbol(const Symbol &);
793-
// Record a name appearing in a USE rename clause
792+
void EraseRenamedUse(const Symbol *);
793+
// Record a name appearing as the target of a USE rename clause
794794
void AddUseRename(const SourceName &name) {
795795
useRenames_.emplace(std::make_pair(name, useModuleScope_));
796796
}
@@ -2775,11 +2775,8 @@ bool ModuleVisitor::Pre(const parser::Only &x) {
27752775
bool ModuleVisitor::Pre(const parser::Rename::Names &x) {
27762776
const auto &localName{std::get<0>(x.t)};
27772777
const auto &useName{std::get<1>(x.t)};
2778-
AddUseRename(useName.source);
27792778
SymbolRename rename{AddUse(localName.source, useName.source)};
2780-
if (rename.use && localName.source != useName.source) {
2781-
EraseRenamedSymbol(*rename.use);
2782-
}
2779+
AddUseRename(useName.source);
27832780
Resolve(useName, rename.use);
27842781
Resolve(localName, rename.local);
27852782
return false;
@@ -2797,9 +2794,6 @@ bool ModuleVisitor::Pre(const parser::Rename::Operators &x) {
27972794
"Logical constant '%s' may not be used as a defined operator"_err_en_US);
27982795
} else {
27992796
SymbolRename rename{AddUse(localInfo.symbolName(), useInfo.symbolName())};
2800-
if (rename.use) {
2801-
EraseRenamedSymbol(*rename.use);
2802-
}
28032797
useInfo.Resolve(rename.use);
28042798
localInfo.Resolve(rename.local);
28052799
}
@@ -2910,17 +2904,20 @@ static bool ConvertToUseError(
29102904
}
29112905
}
29122906

2913-
// If a symbol has previously been USE-associated and did not appear in a USE
2914-
// ONLY clause, erase it from the current scope. This is needed when a name
2915-
// appears in a USE rename clause.
2916-
void ModuleVisitor::EraseRenamedSymbol(const Symbol &useSymbol) {
2917-
const SourceName &name{useSymbol.name()};
2907+
// If a symbol has previously been USE-associated and did not appear in
2908+
// an ONLY clause or renaming, erase it from the current scope. This is
2909+
// necessary when a name appears as the target of a later USE rename clause.
2910+
void ModuleVisitor::EraseRenamedUse(const Symbol *useSymbol) {
2911+
if (!useSymbol) {
2912+
return;
2913+
}
2914+
const SourceName &name{useSymbol->name()};
29182915
if (const Symbol * symbol{FindInScope(name)}) {
2919-
if (auto *useDetails{symbol->detailsIf<UseDetails>()}) {
2916+
if (const auto *useDetails{symbol->detailsIf<UseDetails>()}) {
29202917
const Symbol &moduleSymbol{useDetails->symbol()};
29212918
if (moduleSymbol.name() == name &&
2922-
moduleSymbol.owner() == useSymbol.owner() && IsUseRenamed(name) &&
2923-
!IsUseOnly(name)) {
2919+
moduleSymbol.owner() == useSymbol->owner() && !IsUseOnly(name) &&
2920+
!IsUseRenamed(name)) {
29242921
EraseSymbol(*symbol);
29252922
}
29262923
}
@@ -2930,7 +2927,7 @@ void ModuleVisitor::EraseRenamedSymbol(const Symbol &useSymbol) {
29302927
void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
29312928
Symbol &localSymbol, const Symbol &useSymbol) {
29322929
if (localName != useSymbol.name()) {
2933-
EraseRenamedSymbol(useSymbol);
2930+
EraseRenamedUse(&useSymbol);
29342931
}
29352932
if (auto *details{localSymbol.detailsIf<UseErrorDetails>()}) {
29362933
details->add_occurrence(location, *useModuleScope_);

flang/test/Semantics/modfile41.f90

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,9 @@ subroutine testUse12
9494
!ERROR: 'a' is use-associated from module 'm4' and cannot be re-declared
9595
integer :: a = 2
9696
end
97+
subroutine testUse13
98+
use m1, a => a
99+
use m1, z => a ! should not erase 'a', it was renamed
100+
!ERROR: 'a' is use-associated from module 'm1' and cannot be re-declared
101+
integer :: a = 13
102+
end

0 commit comments

Comments
 (0)