[flang-commits] [flang] 9eab0da - [flang] Catch branching into FORALL/WHERE constructs

peter klausler via flang-commits flang-commits at lists.llvm.org
Mon Sep 27 10:51:57 PDT 2021


Author: peter klausler
Date: 2021-09-27T10:51:44-07:00
New Revision: 9eab0da18320019f85c8c4c58f49a25b05ad40f7

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

LOG: [flang] Catch branching into FORALL/WHERE constructs

Enforce constraints C1034 & C1038, which disallow the use
of otherwise valid statements as branch targets when they
appear in FORALL &/or WHERE constructs.  (And make the
diagnostic message somewhat more user-friendly.)

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

Added: 
    

Modified: 
    flang/lib/Semantics/resolve-labels.cpp
    flang/test/Semantics/label05.f90
    flang/test/Semantics/label06.f90
    flang/test/Semantics/label07.f90
    flang/test/Semantics/label14.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-labels.cpp b/flang/lib/Semantics/resolve-labels.cpp
index 767fe66666a2..ff6105aa3a76 100644
--- a/flang/lib/Semantics/resolve-labels.cpp
+++ b/flang/lib/Semantics/resolve-labels.cpp
@@ -60,7 +60,7 @@ constexpr Legality IsLegalDoTerm(const parser::Statement<A> &) {
       std::is_same_v<A, parser::EndWhereStmt>) {
     // Executable construct end statements are also supported as
     // an extension but they need special care because the associated
-    // construct create there own scope.
+    // construct create their own scope.
     return Legality::formerly;
   } else {
     return Legality::never;
@@ -224,10 +224,10 @@ class ParseTreeAnalyzer {
         parser::BlockStmt, parser::ChangeTeamStmt, parser::CriticalStmt,
         parser::IfThenStmt, parser::NonLabelDoStmt, parser::SelectCaseStmt,
         parser::SelectRankStmt, parser::SelectTypeStmt>;
-    using LabeledConstructEndStmts =
-        std::tuple<parser::EndAssociateStmt, parser::EndBlockStmt,
-            parser::EndChangeTeamStmt, parser::EndCriticalStmt,
-            parser::EndDoStmt, parser::EndIfStmt, parser::EndSelectStmt>;
+    using LabeledConstructEndStmts = std::tuple<parser::EndAssociateStmt,
+        parser::EndBlockStmt, parser::EndChangeTeamStmt,
+        parser::EndCriticalStmt, parser::EndDoStmt, parser::EndForallStmt,
+        parser::EndIfStmt, parser::EndSelectStmt, parser::EndWhereStmt>;
     using LabeledProgramUnitEndStmts =
         std::tuple<parser::EndFunctionStmt, parser::EndMpSubprogramStmt,
             parser::EndProgramStmt, parser::EndSubroutineStmt>;
@@ -294,10 +294,10 @@ class ParseTreeAnalyzer {
     return SwitchToNewScope();
   }
   bool Pre(const parser::WhereConstruct &whereConstruct) {
-    return PushConstructNameWithoutBlock(whereConstruct);
+    return PushConstructName(whereConstruct);
   }
   bool Pre(const parser::ForallConstruct &forallConstruct) {
-    return PushConstructNameWithoutBlock(forallConstruct);
+    return PushConstructName(forallConstruct);
   }
 
   void Post(const parser::AssociateConstruct &associateConstruct) {
@@ -327,12 +327,11 @@ class ParseTreeAnalyzer {
   void Post(const parser::SelectTypeConstruct &selectTypeConstruct) {
     PopConstructName(selectTypeConstruct);
   }
-
   void Post(const parser::WhereConstruct &whereConstruct) {
-    PopConstructNameWithoutBlock(whereConstruct);
+    PopConstructName(whereConstruct);
   }
   void Post(const parser::ForallConstruct &forallConstruct) {
-    PopConstructNameWithoutBlock(forallConstruct);
+    PopConstructName(forallConstruct);
   }
 
   // Checks for missing or mismatching names on various constructs (e.g., IF)
@@ -570,18 +569,6 @@ class ParseTreeAnalyzer {
     }
     return PushSubscope();
   }
-  template <typename A> bool PushConstructNameWithoutBlock(const A &a) {
-    const auto &optionalName{std::get<0>(std::get<0>(a.t).statement.t)};
-    if (optionalName) {
-      constructNames_.emplace_back(optionalName->ToString());
-    }
-    return true;
-  }
-
-  template <typename A> void PopConstructNameWithoutBlock(const A &a) {
-    CheckName(a);
-    PopConstructNameIfPresent(a);
-  }
   template <typename A> void PopConstructNameIfPresent(const A &a) {
     const auto &optionalName{std::get<0>(std::get<0>(a.t).statement.t)};
     if (optionalName) {
@@ -962,12 +949,15 @@ void CheckScopeConstraints(const SourceStmtList &stmts,
     } else if (!InInclusiveScope(scopes, scope, target.proxyForScope)) {
       // Clause 11.1.2.1 prohibits transfer of control to the interior of a
       // block from outside the block, but this does not apply to formats.
+      // C1038 and C1034 forbid statements in FORALL and WHERE constructs
+      // (resp.) from being branch targets.
       if (target.labeledStmtClassificationSet.test(
               TargetStatementEnum::Format)) {
         continue;
       }
-      context.Say(
-          position, "Label '%u' is not in scope"_en_US, SayLabel(label));
+      context.Say(position,
+          "Label '%u' is in a construct that prevents its use as a branch target here"_en_US,
+          SayLabel(label));
     }
   }
 }

diff  --git a/flang/test/Semantics/label05.f90 b/flang/test/Semantics/label05.f90
index 958627acf4b5..7084574a5790 100644
--- a/flang/test/Semantics/label05.f90
+++ b/flang/test/Semantics/label05.f90
@@ -1,9 +1,12 @@
-
 ! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
 ! CHECK: Label '50' was not found
-! CHECK: Label '55' is not in scope
+! CHECK: Label '55' is in a construct that prevents its use as a branch target here
 ! CHECK: Label '70' is not a branch target
 ! CHECK: Control flow use of '70'
+! CHECK: Label '80' is in a construct that prevents its use as a branch target here
+! CHECK: Label '90' is in a construct that prevents its use as a branch target here
+! CHECK: Label '91' is in a construct that prevents its use as a branch target here
+! CHECK: Label '92' is in a construct that prevents its use as a branch target here
 
 subroutine sub00(a,b,n,m)
   real a(n,m)
@@ -35,3 +38,23 @@ subroutine sub02(a,b,n,m)
   end if
 70 FORMAT (1x,i6)
 end subroutine sub02
+
+subroutine sub03(a,n)
+  real a(n)
+  forall (j=1:n)
+80  a(n) = j
+  end forall
+  go to 80
+end subroutine sub03
+
+subroutine sub04(a,n)
+  real a(n)
+  where (a > 0)
+90  a = 1
+  elsewhere (a < 0)
+91  a = 2
+  elsewhere
+92  a = 3
+  end where
+  if (n - 3) 90, 91, 92
+end subroutine sub04

diff  --git a/flang/test/Semantics/label06.f90 b/flang/test/Semantics/label06.f90
index fab521c42ecd..1bccdf19fcbe 100644
--- a/flang/test/Semantics/label06.f90
+++ b/flang/test/Semantics/label06.f90
@@ -1,11 +1,10 @@
-
 ! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
-! CHECK: Label '10' is not in scope
+! CHECK: Label '10' is in a construct that prevents its use as a branch target here
 ! CHECK: Label '20' was not found
 ! CHECK: Label '30' is not a branch target
 ! CHECK: Control flow use of '30'
-! CHECK: Label '40' is not in scope
-! CHECK: Label '50' is not in scope
+! CHECK: Label '40' is in a construct that prevents its use as a branch target here
+! CHECK: Label '50' is in a construct that prevents its use as a branch target here
 
 subroutine sub00(n)
   GOTO (10,20,30) n

diff  --git a/flang/test/Semantics/label07.f90 b/flang/test/Semantics/label07.f90
index 55e2b268933c..3f9af80a826b 100644
--- a/flang/test/Semantics/label07.f90
+++ b/flang/test/Semantics/label07.f90
@@ -1,8 +1,7 @@
-
 ! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
 ! CHECK: Label '30' is not a branch target
 ! CHECK: Control flow use of '30'
-! CHECK: Label '10' is not in scope
+! CHECK: Label '10' is in a construct that prevents its use as a branch target here
 ! CHECK: Label '20' was not found
 ! CHECK: Label '60' was not found
 

diff  --git a/flang/test/Semantics/label14.f90 b/flang/test/Semantics/label14.f90
index 27030c9d0850..f310913f2628 100644
--- a/flang/test/Semantics/label14.f90
+++ b/flang/test/Semantics/label14.f90
@@ -3,7 +3,7 @@
 !            Block Construct
 
 ! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
-! CHECK: Label '20' is not in scope
+! CHECK: Label '20' is in a construct that prevents its use as a branch target here
 
 subroutine s1
   block


        


More information about the flang-commits mailing list