diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -597,6 +597,7 @@ bool inExecutionPart_{false}; bool inSpecificationPart_{false}; + bool inEquivalenceStmt_{false}; std::set specPartForwardRefs_; private: @@ -2021,7 +2022,11 @@ } return FindSymbol(scope.parent(), name); } else { - return Resolve(name, scope.FindSymbol(name.source)); + // In EQUIVALENCE statements only resolve names in the local scope, see + // 19.5.1.4, paragraph 2, item (10) + return Resolve(name, + inEquivalenceStmt_ ? FindInScope(scope, name) + : scope.FindSymbol(name.source)); } } @@ -4347,15 +4352,17 @@ bool DeclarationVisitor::Pre(const parser::EquivalenceStmt &x) { // save equivalence sets to be processed after specification part - CheckNotInBlock("EQUIVALENCE"); // C1107 - for (const std::list &set : x.v) { - equivalenceSets_.push_back(&set); + if (CheckNotInBlock("EQUIVALENCE")) { // C1107 + for (const std::list &set : x.v) { + equivalenceSets_.push_back(&set); + } } return false; // don't implicitly declare names yet } void DeclarationVisitor::CheckEquivalenceSets() { EquivalenceSets equivSets{context()}; + inEquivalenceStmt_ = true; for (const auto *set : equivalenceSets_) { const auto &source{set->front().v.value().source}; if (set->size() <= 1) { // R871 @@ -4372,6 +4379,7 @@ } equivSets.FinishSet(source); } + inEquivalenceStmt_ = false; for (auto &set : equivSets.sets()) { if (!set.empty()) { currScope().add_equivalenceSet(std::move(set)); diff --git a/flang/test/Semantics/equivalence01.f90 b/flang/test/Semantics/equivalence01.f90 --- a/flang/test/Semantics/equivalence01.f90 +++ b/flang/test/Semantics/equivalence01.f90 @@ -197,3 +197,20 @@ end interface end subroutine s16 + +module m17 + real :: dupName +contains + real function f17a() + implicit none + real :: y + !ERROR: No explicit type declared for 'dupname' + equivalence (dupName, y) + end function f17a + real function f17b() + real :: y + ! The following implicitly declares an object called "dupName" local to + ! the function f17b(). OK since there's no "implicit none + equivalence (dupName, y) + end function f17b +end module m17