[llvm-branch-commits] [flang] 4e90cad - [flang] Handle undeclared names in EQUIVALENCE statements

Peter Steinfeld via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Dec 16 11:08:57 PST 2020


Author: Peter Steinfeld
Date: 2020-12-16T11:04:27-08:00
New Revision: 4e90cad6a6b5504f11b7876e26e80c2a079e04b0

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

LOG: [flang] Handle undeclared names in EQUIVALENCE statements

Names in EQUIVALENCE statements are only allowed to indicate local
objects as per 19.5.1.4, paragraph 2, item (10).  Thus, a name appearing
in an EQUIVALENCE statement with no corresponding declaration in the
same scope is an implicit declaration of the name.  If that scope
contains an IMPLICIT NONE, it's an error.

I implemented this by adding a state variable to ScopeHandler to
indicate if we're resolving the names in an EQUIVALENCE statement and
then checked this state when resolving names.  I also added a test to
the existing tests for EQUIVALENCE statements.

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 1288b11a7727..495d7d0f8584 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -597,6 +597,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
 
   bool inExecutionPart_{false};
   bool inSpecificationPart_{false};
+  bool inEquivalenceStmt_{false};
   std::set<SourceName> specPartForwardRefs_;
 
 private:
@@ -2021,7 +2022,11 @@ Symbol *ScopeHandler::FindSymbol(const Scope &scope, const parser::Name &name) {
     }
     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 @@ void DeclarationVisitor::Post(const parser::CommonBlockObject &x) {
 
 bool DeclarationVisitor::Pre(const parser::EquivalenceStmt &x) {
   // save equivalence sets to be processed after specification part
-  CheckNotInBlock("EQUIVALENCE"); // C1107
-  for (const std::list<parser::EquivalenceObject> &set : x.v) {
-    equivalenceSets_.push_back(&set);
+  if (CheckNotInBlock("EQUIVALENCE")) { // C1107
+    for (const std::list<parser::EquivalenceObject> &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 @@ void DeclarationVisitor::CheckEquivalenceSets() {
     }
     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
index 234c42744ee9..e75d954001d7 100644
--- a/flang/test/Semantics/equivalence01.f90
+++ b/flang/test/Semantics/equivalence01.f90
@@ -197,3 +197,20 @@ end subroutine interfaceSub
   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


        


More information about the llvm-branch-commits mailing list