[flang-commits] [flang] [flang] Support kind/index lookup inside of EQUIVALENCE (PR #170056)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Mon Dec 1 19:39:13 PST 2025
https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/170056
>From a9987b69b57eb6034a73bddcc6a1a92cc2bff770 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sat, 29 Nov 2025 22:04:17 -0500
Subject: [PATCH 1/3] Fixed processing of kinds on parameters inside of
equivalence statement
---
flang/lib/Semantics/resolve-names.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 2a487a6d39d51..c17fd96fede50 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6181,6 +6181,11 @@ bool DeclarationVisitor::Pre(const parser::KindParam &x) {
parser::Scalar<parser::Integer<parser::Constant<parser::Name>>>>(
&x.u)}) {
const auto &name{parser::UnwrapRef<parser::Name>(kind)};
+ // For kind params scope resolution, temporarily turn off equivalence
+ // processing, because for equivalences the name resolution is confined
+ // to the current scope. For kind params that may be used for array
+ // indices, we don't want to limit the name resolution to the current scope.
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
if (!FindSymbol(name)) {
Say(name, "Parameter '%s' not found"_err_en_US);
}
>From f074da4637cb3aab8face411b4fc25a4edc27c50 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sat, 29 Nov 2025 22:52:33 -0500
Subject: [PATCH 2/3] Experimentation: seems to work, but may be an overkill
---
flang/lib/Semantics/resolve-names.cpp | 51 ++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 8 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index c17fd96fede50..277a97c7677de 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2153,6 +2153,10 @@ class ResolveNamesVisitor : public virtual ScopeHandler,
void Post(const parser::AssignedGotoStmt &);
void Post(const parser::CompilerDirective &);
+ bool Pre(const parser::ArrayElement &);
+ bool Pre(const parser::Substring &);
+ bool Pre(const parser::CoindexedNamedObject &);
+
// These nodes should never be reached: they are handled in ProgramUnit
bool Pre(const parser::MainProgram &) {
llvm_unreachable("This node is handled in ProgramUnit");
@@ -6181,11 +6185,6 @@ bool DeclarationVisitor::Pre(const parser::KindParam &x) {
parser::Scalar<parser::Integer<parser::Constant<parser::Name>>>>(
&x.u)}) {
const auto &name{parser::UnwrapRef<parser::Name>(kind)};
- // For kind params scope resolution, temporarily turn off equivalence
- // processing, because for equivalences the name resolution is confined
- // to the current scope. For kind params that may be used for array
- // indices, we don't want to limit the name resolution to the current scope.
- auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
if (!FindSymbol(name)) {
Say(name, "Parameter '%s' not found"_err_en_US);
}
@@ -8757,7 +8756,10 @@ const parser::Name *DeclarationVisitor::ResolveDesignator(
common::visitors{
[&](const parser::DataRef &x) { return ResolveDataRef(x); },
[&](const parser::Substring &x) {
- Walk(std::get<parser::SubstringRange>(x.t).t);
+ {
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
+ Walk(std::get<parser::SubstringRange>(x.t).t);
+ }
return ResolveDataRef(std::get<parser::DataRef>(x.t));
},
},
@@ -8773,7 +8775,10 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
return ResolveStructureComponent(y.value());
},
[&](const Indirection<parser::ArrayElement> &y) {
- Walk(y.value().subscripts);
+ {
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
+ Walk(y.value().subscripts);
+ }
const parser::Name *name{ResolveDataRef(y.value().base)};
if (name && name->symbol) {
if (!IsProcedure(*name->symbol)) {
@@ -8787,7 +8792,10 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
return name;
},
[&](const Indirection<parser::CoindexedNamedObject> &y) {
- Walk(y.value().imageSelector);
+ {
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
+ Walk(y.value().imageSelector);
+ }
return ResolveDataRef(y.value().base);
},
},
@@ -10222,6 +10230,33 @@ template <typename A> std::set<SourceName> GetUses(const A &x) {
return uses;
}
+bool ResolveNamesVisitor::Pre(const parser::ArrayElement &x) {
+ Walk(x.base);
+ {
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
+ Walk(x.subscripts);
+ }
+ return false;
+}
+
+bool ResolveNamesVisitor::Pre(const parser::Substring &x) {
+ {
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
+ Walk(std::get<parser::SubstringRange>(x.t).t);
+ }
+ Walk(std::get<parser::DataRef>(x.t));
+ return false;
+}
+
+bool ResolveNamesVisitor::Pre(const parser::CoindexedNamedObject &x) {
+ Walk(x.base);
+ {
+ auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
+ Walk(x.imageSelector);
+ }
+ return false;
+}
+
bool ResolveNamesVisitor::Pre(const parser::Program &x) {
if (Scope * hermetic{context().currentHermeticModuleFileScope()}) {
// Processing either the dependent modules or first module of a
>From 723c160f4114fc9b2c07d2713948750af946b3fe Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 30 Nov 2025 20:03:30 -0500
Subject: [PATCH 3/3] Removed unnecessary changes, added comments
---
flang/lib/Semantics/resolve-names.cpp | 34 +++++----------------------
1 file changed, 6 insertions(+), 28 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 277a97c7677de..ea00c97ad9187 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2154,8 +2154,6 @@ class ResolveNamesVisitor : public virtual ScopeHandler,
void Post(const parser::CompilerDirective &);
bool Pre(const parser::ArrayElement &);
- bool Pre(const parser::Substring &);
- bool Pre(const parser::CoindexedNamedObject &);
// These nodes should never be reached: they are handled in ProgramUnit
bool Pre(const parser::MainProgram &) {
@@ -8756,10 +8754,7 @@ const parser::Name *DeclarationVisitor::ResolveDesignator(
common::visitors{
[&](const parser::DataRef &x) { return ResolveDataRef(x); },
[&](const parser::Substring &x) {
- {
- auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
- Walk(std::get<parser::SubstringRange>(x.t).t);
- }
+ Walk(std::get<parser::SubstringRange>(x.t).t);
return ResolveDataRef(std::get<parser::DataRef>(x.t));
},
},
@@ -8776,6 +8771,8 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
},
[&](const Indirection<parser::ArrayElement> &y) {
{
+ // Turn off "in EQUIVALENCE" check for array indexing, because
+ // the indices themselves are not part of the EQUIVALENCE.
auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
Walk(y.value().subscripts);
}
@@ -8792,10 +8789,7 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
return name;
},
[&](const Indirection<parser::CoindexedNamedObject> &y) {
- {
- auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
- Walk(y.value().imageSelector);
- }
+ Walk(y.value().imageSelector);
return ResolveDataRef(y.value().base);
},
},
@@ -10233,30 +10227,14 @@ template <typename A> std::set<SourceName> GetUses(const A &x) {
bool ResolveNamesVisitor::Pre(const parser::ArrayElement &x) {
Walk(x.base);
{
+ // Turn off "in EQUIVALENCE" check for array indexing, because
+ // the indices themselves are not part of the EQUIVALENCE.
auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
Walk(x.subscripts);
}
return false;
}
-bool ResolveNamesVisitor::Pre(const parser::Substring &x) {
- {
- auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
- Walk(std::get<parser::SubstringRange>(x.t).t);
- }
- Walk(std::get<parser::DataRef>(x.t));
- return false;
-}
-
-bool ResolveNamesVisitor::Pre(const parser::CoindexedNamedObject &x) {
- Walk(x.base);
- {
- auto restorer{common::ScopedSet(inEquivalenceStmt_, false)};
- Walk(x.imageSelector);
- }
- return false;
-}
-
bool ResolveNamesVisitor::Pre(const parser::Program &x) {
if (Scope * hermetic{context().currentHermeticModuleFileScope()}) {
// Processing either the dependent modules or first module of a
More information about the flang-commits
mailing list