[flang-commits] [flang] f75033a - [flang] Add nested scoping to label distinctness checking

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Aug 25 14:54:54 PDT 2022


Author: Peter Klausler
Date: 2022-08-25T14:54:38-07:00
New Revision: f75033a0588a05b0077ad8fedb1dad6f466558c0

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

LOG: [flang] Add nested scoping to label distinctness checking

Fortran defines derived type definitions and explicit interface
blocks for subroutines and functions to be nestable scopes for
statement labels, even though such labels are useless for all
purposes.  Handle these scopes in label resolution so that bogus
errors about conflicting labels in "real" code don't come out.

Note that BLOCK constructs could have also been defined as scopes
for statement labeling, but were not.

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

Added: 
    flang/test/Semantics/label17.f90

Modified: 
    flang/lib/Semantics/resolve-labels.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-labels.cpp b/flang/lib/Semantics/resolve-labels.cpp
index c54740033b10d..b53d2c3823583 100644
--- a/flang/lib/Semantics/resolve-labels.cpp
+++ b/flang/lib/Semantics/resolve-labels.cpp
@@ -374,6 +374,12 @@ class ParseTreeAnalyzer {
         std::get<parser::Statement<parser::EndBlockDataStmt>>(blockData.t));
   }
 
+  bool Pre(const parser::InterfaceBody &) {
+    PushDisposableMap();
+    return true;
+  }
+  void Post(const parser::InterfaceBody &) { PopDisposableMap(); }
+
   // C1564
   void Post(const parser::InterfaceBody::Function &func) {
     CheckOptionalName<parser::FunctionStmt>("FUNCTION", func,
@@ -492,10 +498,15 @@ class ParseTreeAnalyzer {
   }
 
   // C739
+  bool Pre(const parser::DerivedTypeDef &) {
+    PushDisposableMap();
+    return true;
+  }
   void Post(const parser::DerivedTypeDef &derivedTypeDef) {
     CheckOptionalName<parser::DerivedTypeStmt>("derived type definition",
         derivedTypeDef,
         std::get<parser::Statement<parser::EndTypeStmt>>(derivedTypeDef.t));
+    PopDisposableMap();
   }
 
   void Post(const parser::LabelDoStmt &labelDoStmt) {
@@ -779,7 +790,10 @@ class ParseTreeAnalyzer {
       LabeledStmtClassificationSet labeledStmtClassificationSet,
       ProxyForScope scope, bool isExecutableConstructEndStmt = false) {
     CheckLabelInRange(label);
-    const auto pair{programUnits_.back().targetStmts.emplace(label,
+    TargetStmtMap &targetStmtMap{disposableMaps_.empty()
+            ? programUnits_.back().targetStmts
+            : disposableMaps_.back()};
+    const auto pair{targetStmtMap.emplace(label,
         LabeledStatementInfoTuplePOD{scope, currentPosition_,
             labeledStmtClassificationSet, isExecutableConstructEndStmt})};
     if (!pair.second) {
@@ -818,11 +832,19 @@ class ParseTreeAnalyzer {
     }
   }
 
+  void PushDisposableMap() { disposableMaps_.emplace_back(); }
+  void PopDisposableMap() { disposableMaps_.pop_back(); }
+
   std::vector<UnitAnalysis> programUnits_;
   SemanticsContext &context_;
   parser::CharBlock currentPosition_;
   ProxyForScope currentScope_;
   std::vector<std::string> constructNames_;
+  // For labels in derived type definitions and procedure
+  // interfaces, which are their own inclusive scopes.  None
+  // of these labels can be used as a branch target, but they
+  // should be pairwise distinct.
+  std::vector<TargetStmtMap> disposableMaps_;
 };
 
 bool InInclusiveScope(const std::vector<ScopeInfo> &scopes, ProxyForScope tail,

diff  --git a/flang/test/Semantics/label17.f90 b/flang/test/Semantics/label17.f90
new file mode 100644
index 0000000000000..262e0073f1ef9
--- /dev/null
+++ b/flang/test/Semantics/label17.f90
@@ -0,0 +1,38 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+1 program main
+1  type one
+2    real x
+3  end type one
+1  type two
+2    real x
+     !ERROR: Label '2' is not distinct
+2    real y
+3  end type two
+2  interface
+2   subroutine sub1(p, q)
+3    interface
+3     subroutine p
+4     end subroutine
+3     subroutine q
+4     end subroutine
+4    end interface
+5   end subroutine
+2   subroutine sub2(p, q)
+3    interface
+3     subroutine p
+4     end subroutine
+3     subroutine q
+4     end subroutine
+4    end interface
+5   end subroutine
+3  end interface
+4  call sub3
+5 contains
+1  subroutine sub3
+2   continue
+3   block
+     !ERROR: Label '2' is not distinct
+2    continue
+4   end block
+5  end subroutine
+6 end program


        


More information about the flang-commits mailing list