Skip to content

[flang][OpenMP] Parse cancel-directive-name as clause #130146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Mar 10, 2025

Conversation

kparzysz
Copy link
Contributor

@kparzysz kparzysz commented Mar 6, 2025

The cancellable construct names on CANCEL or CANCELLATION POINT directives are actually clauses (with the same names as the corresponding constructs).

Instead of parsing them into a custom structure, parse them as a clause, which will make CANCEL/CANCELLATION POINT follow the same uniform scheme as other constructs ( [()] [clauses]).

kparzysz added 5 commits March 6, 2025 09:38
…ication

The `OmpDirectiveName` class has a source in addition to wrapping the
llvm::omp::Directive.
Accommodate it in OmpDirectiveSpecification, which may become the
primary component of the actual FLUSH construct in the future.
The cancellable construct names on CANCEL or CANCELLATION POINT directives
are actually clauses (with the same names as the corresponding constructs).

Instead of parsing them into a custom structure, parse them as a clause,
which will make CANCEL/CANCELLATION POINT follow the same uniform scheme
as other constructs (<directive> [(<arguments>)] [clauses]).
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:openmp flang:semantics flang:parser clang:openmp OpenMP related changes to Clang labels Mar 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-semantics

Author: Krzysztof Parzyszek (kparzysz)

Changes

The cancellable construct names on CANCEL or CANCELLATION POINT directives are actually clauses (with the same names as the corresponding constructs).

Instead of parsing them into a custom structure, parse them as a clause, which will make CANCEL/CANCELLATION POINT follow the same uniform scheme as other constructs (<directive> [(<arguments>)] [clauses]).


Full diff: https://github.com/llvm/llvm-project/pull/130146.diff

8 Files Affected:

  • (modified) flang/include/flang/Parser/dump-parse-tree.h (+1-1)
  • (modified) flang/include/flang/Parser/parse-tree.h (+8-3)
  • (modified) flang/lib/Parser/openmp-parsers.cpp (+25-6)
  • (modified) flang/lib/Parser/unparse.cpp (+2-3)
  • (modified) flang/lib/Semantics/check-omp-structure.cpp (+95-38)
  • (modified) flang/lib/Semantics/check-omp-structure.h (+4-1)
  • (added) flang/test/Semantics/OpenMP/cancel.f90 (+29)
  • (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+5)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index fcd902d25fa40..004e22a21ecfa 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -546,6 +546,7 @@ class ParseTreeDumper {
 #define GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
 #include "llvm/Frontend/OpenMP/OMP.inc"
   NODE(parser, OmpClauseList)
+  NODE(parser, OmpCancellationConstructTypeClause)
   NODE(parser, OmpContainsClause)
   NODE(parser, OmpCriticalDirective)
   NODE(parser, OmpErrorDirective)
@@ -689,7 +690,6 @@ class ParseTreeDumper {
   NODE(parser, OpenMPAtomicConstruct)
   NODE(parser, OpenMPBlockConstruct)
   NODE(parser, OpenMPCancelConstruct)
-  NODE(OpenMPCancelConstruct, If)
   NODE(parser, OpenMPCancellationPointConstruct)
   NODE(parser, OpenMPConstruct)
   NODE(parser, OpenMPCriticalConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index a197249ebae91..cb0eb884e1193 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4048,6 +4048,12 @@ struct OmpBindClause {
   WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Binding);
 };
 
+// Artificial clause to represent a cancellable construct.
+struct OmpCancellationConstructTypeClause {
+  TUPLE_CLASS_BOILERPLATE(OmpCancellationConstructTypeClause);
+  std::tuple<OmpDirectiveName, std::optional<ScalarLogicalExpr>> t;
+};
+
 // Ref: [5.2:214]
 //
 // contains-clause ->
@@ -4870,15 +4876,14 @@ struct OmpCancelType {
 struct OpenMPCancellationPointConstruct {
   TUPLE_CLASS_BOILERPLATE(OpenMPCancellationPointConstruct);
   CharBlock source;
-  std::tuple<Verbatim, OmpCancelType> t;
+  std::tuple<Verbatim, OmpClauseList> t;
 };
 
 // 2.14.1 cancel -> CANCEL construct-type-clause [ [,] if-clause]
 struct OpenMPCancelConstruct {
   TUPLE_CLASS_BOILERPLATE(OpenMPCancelConstruct);
-  WRAPPER_CLASS(If, ScalarLogicalExpr);
   CharBlock source;
-  std::tuple<Verbatim, OmpCancelType, std::optional<If>> t;
+  std::tuple<Verbatim, OmpClauseList> t;
 };
 
 // Ref: [5.0:254-255], [5.1:287-288], [5.2:322-323]
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 80831db0e7d50..51b2567a3894d 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -803,8 +803,9 @@ TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
 TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
     construct<llvm::omp::Directive>(unwrap(OmpDirectiveNameParser{})))))
 
-TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
-                            parenthesized(Parser<OmpAbsentClause>{}))) ||
+TYPE_PARSER( //
+    "ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
+                    parenthesized(Parser<OmpAbsentClause>{}))) ||
     "ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
     "ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
     "AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
@@ -981,7 +982,24 @@ TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
     "UPDATE" >> construct<OmpClause>(construct<OmpClause::Update>(
                     parenthesized(Parser<OmpUpdateClause>{}))) ||
     "WHEN" >> construct<OmpClause>(construct<OmpClause::When>(
-                  parenthesized(Parser<OmpWhenClause>{}))))
+                  parenthesized(Parser<OmpWhenClause>{}))) ||
+    // Cancellable constructs
+    construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
+        construct<OmpCancellationConstructTypeClause>( //
+            construct<OmpDirectiveName>(verbatim("DO"_id)),
+            maybe(parenthesized(scalarLogicalExpr))))) ||
+    construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
+        construct<OmpCancellationConstructTypeClause>( //
+            construct<OmpDirectiveName>(verbatim("PARALLEL"_id)),
+            maybe(parenthesized(scalarLogicalExpr))))) ||
+    construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
+        construct<OmpCancellationConstructTypeClause>( //
+            construct<OmpDirectiveName>(verbatim("SECTIONS"_id)),
+            maybe(parenthesized(scalarLogicalExpr))))) ||
+    construct<OmpClause>(construct<OmpClause::CancellationConstructType>(
+        construct<OmpCancellationConstructTypeClause>( //
+            construct<OmpDirectiveName>(verbatim("TASKGROUP"_id)),
+            maybe(parenthesized(scalarLogicalExpr))))))
 
 // [Clause, [Clause], ...]
 TYPE_PARSER(sourced(construct<OmpClauseList>(
@@ -1104,11 +1122,11 @@ TYPE_PARSER(sourced(construct<OmpCancelType>(
 
 // 2.14.2 Cancellation Point construct
 TYPE_PARSER(sourced(construct<OpenMPCancellationPointConstruct>(
-    verbatim("CANCELLATION POINT"_tok), Parser<OmpCancelType>{})))
+    verbatim("CANCELLATION POINT"_tok), Parser<OmpClauseList>{})))
 
 // 2.14.1 Cancel construct
 TYPE_PARSER(sourced(construct<OpenMPCancelConstruct>(verbatim("CANCEL"_tok),
-    Parser<OmpCancelType>{}, maybe("IF" >> parenthesized(scalarLogicalExpr)))))
+    Parser<OmpClauseList>{})))
 
 TYPE_PARSER(sourced(construct<OmpFailClause>(
     parenthesized(indirect(Parser<OmpMemoryOrderClause>{})))))
@@ -1192,9 +1210,10 @@ TYPE_PARSER(
     sourced(construct<OpenMPStandaloneConstruct>(
                 Parser<OpenMPSimpleStandaloneConstruct>{}) ||
         construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
-        construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
+        // Try CANCELLATION POINT before CANCEL.
         construct<OpenMPStandaloneConstruct>(
             Parser<OpenMPCancellationPointConstruct>{}) ||
+        construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
         construct<OpenMPStandaloneConstruct>(
             Parser<OmpMetadirectiveDirective>{}) ||
         construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 12d86653a2b95..11ce214450d96 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2851,15 +2851,14 @@ class UnparseVisitor {
   void Unparse(const OpenMPCancellationPointConstruct &x) {
     BeginOpenMP();
     Word("!$OMP CANCELLATION POINT ");
-    Walk(std::get<OmpCancelType>(x.t));
+    Walk(std::get<OmpClauseList>(x.t));
     Put("\n");
     EndOpenMP();
   }
   void Unparse(const OpenMPCancelConstruct &x) {
     BeginOpenMP();
     Word("!$OMP CANCEL ");
-    Walk(std::get<OmpCancelType>(x.t));
-    Walk(std::get<std::optional<OpenMPCancelConstruct::If>>(x.t));
+    Walk(std::get<OmpClauseList>(x.t));
     Put("\n");
     EndOpenMP();
   }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 64a0be703744d..8d819defb4a0c 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2176,9 +2176,13 @@ void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) {
 
 void OmpStructureChecker::Enter(const parser::OpenMPCancelConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  const auto &type{std::get<parser::OmpCancelType>(x.t)};
+  const auto &clauses{std::get<parser::OmpClauseList>(x.t)};
   PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_cancel);
-  CheckCancellationNest(dir.source, type.v);
+
+  if (auto maybeConstruct{GetCancelType(
+          llvm::omp::Directive::OMPD_cancel, x.source, clauses)}) {
+    CheckCancellationNest(dir.source, *maybeConstruct);
+  }
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
@@ -2228,13 +2232,38 @@ void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) {
   dirContext_.pop_back();
 }
 
+void OmpStructureChecker::Enter(
+    const parser::OmpClause::CancellationConstructType &x) {
+  // Do not call CheckAllowed/CheckAllowedClause, because in case of an error
+  // it will print "CANCELLATION_CONSTRUCT_TYPE" as the clause name instead of
+  // the contained construct name.
+  auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)};
+  switch (dirName.v) {
+  case llvm::omp::Directive::OMPD_do:
+  case llvm::omp::Directive::OMPD_parallel:
+  case llvm::omp::Directive::OMPD_sections:
+  case llvm::omp::Directive::OMPD_taskgroup:
+    break;
+  default:
+    context_.Say(dirName.source,
+        "%s is not a cancellable construct"_err_en_US,
+        parser::ToUpperCaseLetters(
+            llvm::omp::getOpenMPDirectiveName(dirName.v).str()));
+    break;
+  }
+}
+
 void OmpStructureChecker::Enter(
     const parser::OpenMPCancellationPointConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
-  const auto &type{std::get<parser::OmpCancelType>(x.t)};
+  const auto &clauses{std::get<parser::OmpClauseList>(x.t)};
   PushContextAndClauseSets(
       dir.source, llvm::omp::Directive::OMPD_cancellation_point);
-  CheckCancellationNest(dir.source, type.v);
+
+  if (auto maybeConstruct{GetCancelType(
+          llvm::omp::Directive::OMPD_cancellation_point, x.source, clauses)}) {
+    CheckCancellationNest(dir.source, *maybeConstruct);
+  }
 }
 
 void OmpStructureChecker::Leave(
@@ -2242,8 +2271,42 @@ void OmpStructureChecker::Leave(
   dirContext_.pop_back();
 }
 
+std::optional<llvm::omp::Directive> OmpStructureChecker::GetCancelType(
+    llvm::omp::Directive cancelDir, const parser::CharBlock &cancelSource,
+    const parser::OmpClauseList &clauses) {
+  // Given clauses from CANCEL or CANCELLATION_POINT, identify the construct
+  // to which the cancellation applies.
+  std::optional<llvm::omp::Directive> cancelee;
+  llvm::StringRef cancelName{llvm::omp::getOpenMPDirectiveName(cancelDir)};
+
+  for (const parser::OmpClause &clause : clauses.v) {
+    using CancellationConstructType =
+        parser::OmpClause::CancellationConstructType;
+    if (auto *cctype{std::get_if<CancellationConstructType>(&clause.u)}) {
+      if (cancelee) {
+        context_.Say(cancelSource,
+            "Multiple cancel-directive-name clauses are not allowed on the %s construct"_err_en_US,
+            parser::ToUpperCaseLetters(cancelName.str()));
+        return std::nullopt;
+      }
+      cancelee = std::get<parser::OmpDirectiveName>(cctype->v.t).v;
+    }
+  }
+
+  if (!cancelee) {
+    context_.Say(cancelSource,
+        "Missing cancel-directive-name clause on the %s construct"_err_en_US,
+        parser::ToUpperCaseLetters(cancelName.str()));
+    return std::nullopt;
+  }
+
+  return cancelee;
+}
+
 void OmpStructureChecker::CheckCancellationNest(
-    const parser::CharBlock &source, const parser::OmpCancelType::Type &type) {
+    const parser::CharBlock &source, llvm::omp::Directive type) {
+  llvm::StringRef typeName{llvm::omp::getOpenMPDirectiveName(type)};
+
   if (CurrentDirectiveIsNested()) {
     // If construct-type-clause is taskgroup, the cancellation construct must be
     // closely nested inside a task or a taskloop construct and the cancellation
@@ -2254,8 +2317,9 @@ void OmpStructureChecker::CheckCancellationNest(
     // that matches the type specified in construct-type-clause of the
     // cancellation construct.
     bool eligibleCancellation{false};
+
     switch (type) {
-    case parser::OmpCancelType::Type::Taskgroup:
+    case llvm::omp::Directive::OMPD_taskgroup:
       if (llvm::omp::nestedCancelTaskgroupAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
@@ -2281,38 +2345,37 @@ void OmpStructureChecker::CheckCancellationNest(
       }
       if (!eligibleCancellation) {
         context_.Say(source,
-            "With %s clause, %s construct must be closely nested inside TASK "
-            "or TASKLOOP construct and %s region must be closely nested inside "
-            "TASKGROUP region"_err_en_US,
-            parser::ToUpperCaseLetters(
-                parser::OmpCancelType::EnumToString(type)),
+            "With %s clause, %s construct must be closely nested inside TASK or TASKLOOP construct and %s region must be closely nested inside TASKGROUP region"_err_en_US,
+            parser::ToUpperCaseLetters(typeName.str()),
             ContextDirectiveAsFortran(), ContextDirectiveAsFortran());
       }
       return;
-    case parser::OmpCancelType::Type::Sections:
+    case llvm::omp::Directive::OMPD_sections:
       if (llvm::omp::nestedCancelSectionsAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
       }
       break;
-    case parser::OmpCancelType::Type::Do:
+    case llvm::omp::Directive::OMPD_do:
       if (llvm::omp::nestedCancelDoAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
       }
       break;
-    case parser::OmpCancelType::Type::Parallel:
+    case llvm::omp::Directive::OMPD_parallel:
       if (llvm::omp::nestedCancelParallelAllowedSet.test(
               GetContextParent().directive)) {
         eligibleCancellation = true;
       }
       break;
+    default:
+      // This should have been diagnosed by this point.
+      llvm_unreachable("Unexpected directive");
     }
     if (!eligibleCancellation) {
       context_.Say(source,
-          "With %s clause, %s construct cannot be closely nested inside %s "
-          "construct"_err_en_US,
-          parser::ToUpperCaseLetters(parser::OmpCancelType::EnumToString(type)),
+          "With %s clause, %s construct cannot be closely nested inside %s construct"_err_en_US,
+          parser::ToUpperCaseLetters(typeName.str()),
           ContextDirectiveAsFortran(),
           parser::ToUpperCaseLetters(
               getDirectiveName(GetContextParent().directive).str()));
@@ -2320,38 +2383,33 @@ void OmpStructureChecker::CheckCancellationNest(
   } else {
     // The cancellation directive cannot be orphaned.
     switch (type) {
-    case parser::OmpCancelType::Type::Taskgroup:
+    case llvm::omp::Directive::OMPD_taskgroup:
       context_.Say(source,
-          "%s %s directive is not closely nested inside "
-          "TASK or TASKLOOP"_err_en_US,
+          "%s %s directive is not closely nested inside TASK or TASKLOOP"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(typeName.str()));
       break;
-    case parser::OmpCancelType::Type::Sections:
+    case llvm::omp::Directive::OMPD_sections:
       context_.Say(source,
-          "%s %s directive is not closely nested inside "
-          "SECTION or SECTIONS"_err_en_US,
+          "%s %s directive is not closely nested inside SECTION or SECTIONS"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(typeName.str()));
       break;
-    case parser::OmpCancelType::Type::Do:
+    case llvm::omp::Directive::OMPD_do:
       context_.Say(source,
-          "%s %s directive is not closely nested inside "
-          "the construct that matches the DO clause type"_err_en_US,
+          "%s %s directive is not closely nested inside the construct that matches the DO clause type"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(typeName.str()));
       break;
-    case parser::OmpCancelType::Type::Parallel:
+    case llvm::omp::Directive::OMPD_parallel:
       context_.Say(source,
-          "%s %s directive is not closely nested inside "
-          "the construct that matches the PARALLEL clause type"_err_en_US,
+          "%s %s directive is not closely nested inside the construct that matches the PARALLEL clause type"_err_en_US,
           ContextDirectiveAsFortran(),
-          parser::ToUpperCaseLetters(
-              parser::OmpCancelType::EnumToString(type)));
+          parser::ToUpperCaseLetters(typeName.str()));
       break;
+    default:
+      // This should have been diagnosed by this point.
+      llvm_unreachable("Unexpected directive");
     }
   }
 }
@@ -3044,7 +3102,6 @@ CHECK_SIMPLE_CLAUSE(MemoryOrder, OMPC_memory_order)
 CHECK_SIMPLE_CLAUSE(Bind, OMPC_bind)
 CHECK_SIMPLE_CLAUSE(Align, OMPC_align)
 CHECK_SIMPLE_CLAUSE(Compare, OMPC_compare)
-CHECK_SIMPLE_CLAUSE(CancellationConstructType, OMPC_cancellation_construct_type)
 CHECK_SIMPLE_CLAUSE(OmpxAttribute, OMPC_ompx_attribute)
 CHECK_SIMPLE_CLAUSE(Weak, OMPC_weak)
 
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index b70ea58cf5578..48795995fdf50 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -275,8 +275,11 @@ class OmpStructureChecker
   void CheckTargetUpdate();
   void CheckDependenceType(const parser::OmpDependenceType::Value &x);
   void CheckTaskDependenceType(const parser::OmpTaskDependenceType::Value &x);
+  std::optional<llvm::omp::Directive> GetCancelType(
+      llvm::omp::Directive cancelDir, const parser::CharBlock &cancelSource,
+      const parser::OmpClauseList &clauses);
   void CheckCancellationNest(
-      const parser::CharBlock &source, const parser::OmpCancelType::Type &type);
+      const parser::CharBlock &source, llvm::omp::Directive type);
   std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);
   void CheckReductionObjects(
       const parser::OmpObjectList &objects, llvm::omp::Clause clauseId);
diff --git a/flang/test/Semantics/OpenMP/cancel.f90 b/flang/test/Semantics/OpenMP/cancel.f90
new file mode 100644
index 0000000000000..581c4bdb97646
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/cancel.f90
@@ -0,0 +1,29 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+subroutine f00
+!$omp parallel
+!ERROR: Missing cancel-directive-name clause on the CANCEL construct
+!$omp cancel
+!$omp end parallel
+end
+
+subroutine f01
+!$omp parallel
+!ERROR: Multiple cancel-directive-name clauses are not allowed on the CANCEL construct
+!$omp cancel parallel parallel
+!$omp end parallel
+end
+
+subroutine f02
+!$omp parallel
+!ERROR: Missing cancel-directive-name clause on the CANCELLATION POINT construct
+!$omp cancellation point
+!$omp end parallel
+end
+
+subroutine f03
+!$omp parallel
+!ERROR: Multiple cancel-directive-name clauses are not allowed on the CANCELLATION POINT construct
+!$omp cancellation point parallel parallel
+!$omp end parallel
+end
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 8a2f30a7995dc..cbad02a70609f 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -105,6 +105,7 @@ def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
     OMP_CANCELLATION_CONSTRUCT_Taskgroup,
     OMP_CANCELLATION_CONSTRUCT_None
   ];
+  let flangClass = "OmpCancellationConstructTypeClause";
 }
 def OMPC_Contains : Clause<"contains"> {
   let clangClass = "OMPContainsClause";
@@ -647,12 +648,16 @@ def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {
 }
 def OMP_Cancel : Directive<"cancel"> {
   let allowedOnceClauses = [
+    VersionedClause<OMPC_CancellationConstructType>,
     VersionedClause<OMPC_If>,
   ];
   let association = AS_None;
   let category = CA_Executable;
 }
 def OMP_CancellationPoint : Directive<"cancellation point"> {
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_CancellationConstructType>,
+  ];
   let association = AS_None;
   let category = CA_Executable;
 }

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG.

Base automatically changed from users/kparzysz/spr/o02-metadirective-flush to main March 10, 2025 13:12
@kparzysz kparzysz merged commit 5ba7a3b into main Mar 10, 2025
11 checks passed
@kparzysz kparzysz deleted the users/kparzysz/spr/o03-cancel-directive-name branch March 10, 2025 16:58
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 10, 2025

LLVM Buildbot has detected a new failure on builder sanitizer-aarch64-linux running on sanitizer-buildbot8 while building flang,llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/12276

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
[182/186] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.aarch64-with-call.o
[183/186] Generating Msan-aarch64-with-call-Test
[184/186] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.aarch64.o
[185/186] Generating Msan-aarch64-Test
[185/186] Running compiler_rt regression tests
llvm-lit: /home/b/sanitizer-aarch64-linux/build/llvm-project/llvm/utils/lit/lit/discovery.py:276: warning: input '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/interception/Unit' contained no tests
llvm-lit: /home/b/sanitizer-aarch64-linux/build/llvm-project/llvm/utils/lit/lit/discovery.py:276: warning: input '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/sanitizer_common/Unit' contained no tests
llvm-lit: /home/b/sanitizer-aarch64-linux/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 6131 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
FAIL: libFuzzer-aarch64-static-libcxx-Linux :: reduce_inputs.test (6076 of 6131)
******************** TEST 'libFuzzer-aarch64-static-libcxx-Linux :: reduce_inputs.test' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 3: rm -rf /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
+ rm -rf /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
RUN: at line 4: mkdir -p /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
+ mkdir -p /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
RUN: at line 5: /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang    -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer  -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta  /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowSimpleTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest
+ /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowSimpleTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest
RUN: at line 6: /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang    -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer  -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta  /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowTest
+ /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowTest
RUN: at line 7: /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest  -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60   -runs=1000000 /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C 2>&1 | FileCheck /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test
+ FileCheck /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test
+ /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test:8:8: error: CHECK: expected string not found in input
CHECK: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60'
       ^
<stdin>:1:1: note: scanning from here
INFO: Running with entropic power schedule (0xFF, 100).
^

Input file: <stdin>
Check file: /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test

-dump-input=help explains the following input dump.

Input was:
<<<<<<
         1: INFO: Running with entropic power schedule (0xFF, 100). 
check:8     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
         2: INFO: Seed: 1243266813 
check:8     ~~~~~~~~~~~~~~~~~~~~~~~
         3: INFO: Loaded 1 modules (6 inline 8-bit counters): 6 [0xbf3c5fdacfe0, 0xbf3c5fdacfe6),  
check:8     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         4: INFO: Loaded 1 PC tables (6 PCs): 6 [0xbf3c5fdacfe8,0xbf3c5fdad048),  
check:8     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Step 14 (test compiler-rt default) failure: test compiler-rt default (failure)
...
[182/186] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.aarch64-with-call.o
[183/186] Generating Msan-aarch64-with-call-Test
[184/186] Generating MSAN_INST_TEST_OBJECTS.msan_test.cpp.aarch64.o
[185/186] Generating Msan-aarch64-Test
[185/186] Running compiler_rt regression tests
llvm-lit: /home/b/sanitizer-aarch64-linux/build/llvm-project/llvm/utils/lit/lit/discovery.py:276: warning: input '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/interception/Unit' contained no tests
llvm-lit: /home/b/sanitizer-aarch64-linux/build/llvm-project/llvm/utils/lit/lit/discovery.py:276: warning: input '/home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/sanitizer_common/Unit' contained no tests
llvm-lit: /home/b/sanitizer-aarch64-linux/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 6131 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
FAIL: libFuzzer-aarch64-static-libcxx-Linux :: reduce_inputs.test (6076 of 6131)
******************** TEST 'libFuzzer-aarch64-static-libcxx-Linux :: reduce_inputs.test' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 3: rm -rf /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
+ rm -rf /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
RUN: at line 4: mkdir -p /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
+ mkdir -p /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
RUN: at line 5: /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang    -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer  -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta  /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowSimpleTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest
+ /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowSimpleTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest
RUN: at line 6: /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang    -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer  -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta  /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowTest
+ /home/b/sanitizer-aarch64-linux/build/build_default/./bin/clang -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/lib/fuzzer -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/ShrinkControlFlowTest.cpp -o /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowTest
RUN: at line 7: /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest  -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60   -runs=1000000 /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C 2>&1 | FileCheck /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test
+ FileCheck /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test
+ /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp-ShrinkControlFlowSimpleTest -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 /home/b/sanitizer-aarch64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/fuzzer/AARCH64StaticLibcxxLinuxConfig/Output/reduce_inputs.test.tmp/C
/home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test:8:8: error: CHECK: expected string not found in input
CHECK: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60'
       ^
<stdin>:1:1: note: scanning from here
INFO: Running with entropic power schedule (0xFF, 100).
^

Input file: <stdin>
Check file: /home/b/sanitizer-aarch64-linux/build/llvm-project/compiler-rt/test/fuzzer/reduce_inputs.test

-dump-input=help explains the following input dump.

Input was:
<<<<<<
         1: INFO: Running with entropic power schedule (0xFF, 100). 
check:8     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
         2: INFO: Seed: 1243266813 
check:8     ~~~~~~~~~~~~~~~~~~~~~~~
         3: INFO: Loaded 1 modules (6 inline 8-bit counters): 6 [0xbf3c5fdacfe0, 0xbf3c5fdacfe6),  
check:8     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         4: INFO: Loaded 1 PC tables (6 PCs): 6 [0xbf3c5fdacfe8,0xbf3c5fdad048),  
check:8     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:openmp OpenMP related changes to Clang flang:openmp flang:parser flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants