[flang-commits] [flang] c585888 - [flang][OpenMP] Remove now unused OmpVerifyModifiers (#220677)

via flang-commits flang-commits at lists.llvm.org
Thu Sep 3 09:57:58 PDT 2026


Author: Krzysztof Parzyszek
Date: 2026-09-03T11:57:41-05:00
New Revision: c5858886c7ad7f0c864fe2b6026dbc363c8a651d

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

LOG: [flang][OpenMP] Remove now unused OmpVerifyModifiers (#220677)

Its functionality has been subsumed by VerifyModifiers.

Added: 
    

Modified: 
    flang/include/flang/Semantics/openmp-modifiers.h
    flang/lib/Semantics/check-omp-loop.cpp
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/lib/Semantics/check-omp-variant.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h
index a045a92b951e4..2045749f2e59f 100644
--- a/flang/include/flang/Semantics/openmp-modifiers.h
+++ b/flang/include/flang/Semantics/openmp-modifiers.h
@@ -192,12 +192,6 @@ Fortran::parser::CharBlock OmpGetModifierSource(
   }
   llvm_unreachable("`specific` must be a member of `modifiers`");
 }
-
-template <typename ClauseTy>
-bool OmpVerifyModifiers(const ClauseTy &clause, llvm::omp::Clause id,
-    parser::CharBlock clauseSource, SemanticsContext &semaCtx) {
-  return true;
-}
 } // namespace Fortran::semantics
 
 #endif // FORTRAN_SEMANTICS_OPENMP_MODIFIERS_H_

diff  --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 052b742d5c667..e4ee6020c08d0 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -762,7 +762,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
 void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
   llvm::omp::Directive dir{GetContext().directive};
-  parser::CharBlock clauseSource{GetContext().clauseSource};
   const parser::OmpLinearModifier *linearMod{nullptr};
 
   SymbolSourceMap symbols;
@@ -780,61 +779,59 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
     }
   }};
 
-  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_linear, clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    linearMod = OmpGetUniqueModifier<parser::OmpLinearModifier>(modifiers);
-    if (linearMod) {
-      auto &desc{llvm::omp::getDescriptor(llvm::omp::Modifier::LinearModifier)};
-      parser::CharBlock modSource{OmpGetModifierSource(modifiers, linearMod)};
-      bool valid{true};
-
-      if (version < 52) {
-        // Modifiers on LINEAR are only allowed on DECLARE SIMD
+  auto &modifiers{OmpGetModifiers(x.v)};
+  linearMod = OmpGetUniqueModifier<parser::OmpLinearModifier>(modifiers);
+  if (linearMod) {
+    auto &desc{llvm::omp::getDescriptor(llvm::omp::Modifier::LinearModifier)};
+    parser::CharBlock modSource{OmpGetModifierSource(modifiers, linearMod)};
+    bool valid{true};
+
+    if (version < 52) {
+      // Modifiers on LINEAR are only allowed on DECLARE SIMD
+      if (dir != llvm::omp::Directive::OMPD_declare_simd) {
+        context_.Say(modSource,
+            "A modifier may not be specified in a LINEAR clause on the %s directive"_err_en_US,
+            parser::omp::GetUpperName(dir, version));
+        valid = false;
+      }
+    } else {
+      if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
+          linearMod->v == parser::OmpLinearModifier::Value::Uval) {
         if (dir != llvm::omp::Directive::OMPD_declare_simd) {
           context_.Say(modSource,
-              "A modifier may not be specified in a LINEAR clause on the %s directive"_err_en_US,
-              parser::omp::GetUpperName(dir, version));
+              "A REF or UVAL '%s' may not be specified in a LINEAR clause on the %s directive"_err_en_US,
+              desc.getName().str(), parser::omp::GetUpperName(dir, version));
           valid = false;
         }
-      } else {
-        if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
-            linearMod->v == parser::OmpLinearModifier::Value::Uval) {
-          if (dir != llvm::omp::Directive::OMPD_declare_simd) {
-            context_.Say(modSource,
-                "A REF or UVAL '%s' may not be specified in a LINEAR clause on the %s directive"_err_en_US,
-                desc.getName().str(), parser::omp::GetUpperName(dir, version));
-            valid = false;
-          }
-        }
-        if (!std::get</*PostModified=*/bool>(x.v.t)) {
-          context_.Say(modSource,
-              "The 'modifier(<list>)' syntax is deprecated in %s, use '<list> : modifier' instead"_warn_en_US,
-              ThisVersion(version));
-        }
       }
+      if (!std::get</*PostModified=*/bool>(x.v.t)) {
+        context_.Say(modSource,
+            "The 'modifier(<list>)' syntax is deprecated in %s, use '<list> : modifier' instead"_warn_en_US,
+            ThisVersion(version));
+      }
+    }
 
-      if (valid) {
-        for (auto &[symbol, source] : symbols) {
-          if (linearMod->v != parser::OmpLinearModifier::Value::Ref) {
-            CheckIntegerNoRef(symbol, source);
-          } else {
-            if (!IsAllocatable(*symbol) && !IsAssumedShape(*symbol) &&
-                !IsPolymorphic(*symbol)) {
-              context_.Say(source,
-                  "The list item `%s` specified with the REF '%s' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute"_err_en_US,
-                  symbol->name(), desc.getName().str());
-            }
+    if (valid) {
+      for (auto &[symbol, source] : symbols) {
+        if (linearMod->v != parser::OmpLinearModifier::Value::Ref) {
+          CheckIntegerNoRef(symbol, source);
+        } else {
+          if (!IsAllocatable(*symbol) && !IsAssumedShape(*symbol) &&
+              !IsPolymorphic(*symbol)) {
+            context_.Say(source,
+                "The list item `%s` specified with the REF '%s' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute"_err_en_US,
+                symbol->name(), desc.getName().str());
           }
-          if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
-              linearMod->v == parser::OmpLinearModifier::Value::Uval) {
-            if (!IsDummy(*symbol) || IsValue(*symbol)) {
-              context_.Say(source,
-                  "If the `%s` is REF or UVAL, the list item '%s' must be a dummy argument without the VALUE attribute"_err_en_US,
-                  desc.getName().str(), symbol->name());
-            }
+        }
+        if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
+            linearMod->v == parser::OmpLinearModifier::Value::Uval) {
+          if (!IsDummy(*symbol) || IsValue(*symbol)) {
+            context_.Say(source,
+                "If the `%s` is REF or UVAL, the list item '%s' must be a dummy argument without the VALUE attribute"_err_en_US,
+                desc.getName().str(), symbol->name());
           }
-        } // for (symbol, source)
-      }
+        }
+      } // for (symbol, source)
     }
   }
 
@@ -959,8 +956,6 @@ void OmpStructureChecker::Enter(const parser::OmpLoopModifier &x) {
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Apply &x) {
   EnterDirectiveNest(ApplyNest);
-  OmpVerifyModifiers(
-      x.v, llvm::omp::Clause::OMPC_apply, GetContext().clauseSource, context_);
 }
 
 void OmpStructureChecker::Leave(const parser::OmpClause::Apply &x) {

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 9c77960ac12cb..a238313ecf3fd 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1261,12 +1261,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Hint &x) {
   }
 }
 
-void OmpStructureChecker::Enter(const parser::OmpClause::DynGroupprivate &x) {
-  parser::CharBlock source{GetContext().clauseSource};
-
-  OmpVerifyModifiers(x.v, llvm::omp::OMPC_dyn_groupprivate, source, context_);
-}
-
 template <typename Checker> struct DirectiveSpellingVisitor {
   using Directive = llvm::omp::Directive;
 
@@ -2147,11 +2141,6 @@ void OmpStructureChecker::CheckInitOnDepobj(
   CheckTypeParamInquiry(initClause.source, std::get<parser::OmpObject>(init.t),
       llvm::omp::Clause::OMPC_init);
 
-  if (!OmpVerifyModifiers(
-          init, llvm::omp::Clause::OMPC_init, initClause.source, context_)) {
-    return;
-  }
-
   auto &modifiers{OmpGetModifiers(init)};
   if (auto *depInfo{
           OmpGetUniqueModifier<parser::OmpDepinfoModifier>(modifiers)}) {
@@ -2523,18 +2512,14 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) {
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) {
-  if (OmpVerifyModifiers(
-          x.v, llvm::omp::OMPC_allocate, GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    if (auto *align{
-            OmpGetUniqueModifier<parser::OmpAlignModifier>(modifiers)}) {
-      if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
-        context_.Say(OmpGetModifierSource(modifiers, align),
-            "The alignment value should be a constant positive integer"_err_en_US);
-      } else if (!llvm::isPowerOf2_64(*v)) {
-        context_.Say(OmpGetModifierSource(modifiers, align),
-            "The alignment value should be a power of 2"_err_en_US);
-      }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  if (auto *align{OmpGetUniqueModifier<parser::OmpAlignModifier>(modifiers)}) {
+    if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
+      context_.Say(OmpGetModifierSource(modifiers, align),
+          "The alignment value should be a constant positive integer"_err_en_US);
+    } else if (!llvm::isPowerOf2_64(*v)) {
+      context_.Say(OmpGetModifierSource(modifiers, align),
+          "The alignment value should be a power of 2"_err_en_US);
     }
   }
 
@@ -3940,21 +3925,17 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Destroy &x) {
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) {
   auto &objects{*GetOmpObjectList(x)};
-
-  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_reduction,
-          GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    const auto *ident{
-        OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
-    assert(ident && "reduction-identifier is a required modifier");
-    if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident),
-            llvm::omp::OMPC_reduction)) {
-      CheckReductionObjectTypes(objects, *ident);
-    }
-    using ReductionModifier = parser::OmpReductionModifier;
-    if (auto *modifier{OmpGetUniqueModifier<ReductionModifier>(modifiers)}) {
-      CheckReductionModifier(*modifier);
-    }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  const auto *ident{
+      OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
+  assert(ident && "reduction-identifier is a required modifier");
+  if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident),
+          llvm::omp::OMPC_reduction)) {
+    CheckReductionObjectTypes(objects, *ident);
+  }
+  using ReductionModifier = parser::OmpReductionModifier;
+  if (auto *modifier{OmpGetUniqueModifier<ReductionModifier>(modifiers)}) {
+    CheckReductionModifier(*modifier);
   }
   CheckReductionObjects(objects, llvm::omp::Clause::OMPC_reduction);
 
@@ -3979,34 +3960,26 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) {
 
 void OmpStructureChecker::Enter(const parser::OmpClause::InReduction &x) {
   auto &objects{*GetOmpObjectList(x)};
-
-  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_in_reduction,
-          GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    const auto *ident{
-        OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
-    assert(ident && "reduction-identifier is a required modifier");
-    if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident),
-            llvm::omp::OMPC_in_reduction)) {
-      CheckReductionObjectTypes(objects, *ident);
-    }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  const auto *ident{
+      OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
+  assert(ident && "reduction-identifier is a required modifier");
+  if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident),
+          llvm::omp::OMPC_in_reduction)) {
+    CheckReductionObjectTypes(objects, *ident);
   }
   CheckReductionObjects(objects, llvm::omp::Clause::OMPC_in_reduction);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::TaskReduction &x) {
   auto &objects{*GetOmpObjectList(x)};
-
-  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_task_reduction,
-          GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    const auto *ident{
-        OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
-    assert(ident && "reduction-identifier is a required modifier");
-    if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident),
-            llvm::omp::OMPC_task_reduction)) {
-      CheckReductionObjectTypes(objects, *ident);
-    }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  const auto *ident{
+      OmpGetUniqueModifier<parser::OmpReductionIdentifier>(modifiers)};
+  assert(ident && "reduction-identifier is a required modifier");
+  if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident),
+          llvm::omp::OMPC_task_reduction)) {
+    CheckReductionObjectTypes(objects, *ident);
   }
   CheckReductionObjects(objects, llvm::omp::Clause::OMPC_task_reduction);
 }
@@ -4567,19 +4540,16 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Align &x) {
 // Restrictions specific to each clause are implemented apart from the
 // generalized restrictions.
 void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) {
-  if (OmpVerifyModifiers(
-          x.v, llvm::omp::OMPC_aligned, GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    if (auto *align{OmpGetUniqueModifier<parser::OmpAlignment>(modifiers)}) {
-      const auto &v{GetIntValue(align->v)};
-      if (!v || *v <= 0) {
-        context_.Say(OmpGetModifierSource(modifiers, align),
-            "The alignment value should be a constant positive integer"_err_en_US);
-      } else if (((*v) & (*v - 1)) != 0) {
-        context_.Warn(common::UsageWarning::OpenMPUsage,
-            OmpGetModifierSource(modifiers, align),
-            "Alignment is not a power of 2, Aligned clause will be ignored"_warn_en_US);
-      }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  if (auto *align{OmpGetUniqueModifier<parser::OmpAlignment>(modifiers)}) {
+    const auto &v{GetIntValue(align->v)};
+    if (!v || *v <= 0) {
+      context_.Say(OmpGetModifierSource(modifiers, align),
+          "The alignment value should be a constant positive integer"_err_en_US);
+    } else if (((*v) & (*v - 1)) != 0) {
+      context_.Warn(common::UsageWarning::OpenMPUsage,
+          OmpGetModifierSource(modifiers, align),
+          "Alignment is not a power of 2, Aligned clause will be ignored"_warn_en_US);
     }
   }
   // 2.8.1 TODO: list-item attribute check
@@ -4598,11 +4568,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) {
           ThisVersion(version), TryVersion(llvm::omp::Version(50)));
     }
   }
-  if (!OmpVerifyModifiers(x.v, llvm::omp::OMPC_defaultmap,
-          GetContext().clauseSource, context_)) {
-    // If modifier verification fails, return early.
-    return;
-  }
+
   auto &modifiers{OmpGetModifiers(x.v)};
   auto *maybeCategory{
       OmpGetUniqueModifier<parser::OmpVariableCategory>(modifiers)};
@@ -4658,11 +4624,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
   // diagnostics.
   llvm::omp::Directive appliesTo{llvm::omp::Directive::OMPD_unknown};
 
-  if (!OmpVerifyModifiers(
-          x.v, llvm::omp::OMPC_if, GetContext().clauseSource, context_)) {
-    return;
-  }
-
   auto &modifiers{OmpGetModifiers(x.v)};
   if (auto *dnm{
           OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(modifiers)}) {
@@ -4808,11 +4769,6 @@ void OmpStructureChecker::CheckAllowedMapTypes(parser::OmpMapType::Value type,
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
-  if (!OmpVerifyModifiers(
-          x.v, llvm::omp::OMPC_map, GetContext().clauseSource, context_)) {
-    return;
-  }
-
   auto &modifiers{OmpGetModifiers(x.v)};
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
   if (auto commas{std::get<bool>(x.v.t)}; !commas && version >= 52) {
@@ -4988,10 +4944,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
   const parser::OmpScheduleClause &scheduleClause = x.v;
-  if (!OmpVerifyModifiers(scheduleClause, llvm::omp::OMPC_schedule,
-          GetContext().clauseSource, context_)) {
-    return;
-  }
 
   // 2.7 Loop Construct Restriction
   if (llvm::omp::allDoSet.test(GetContext().directive)) {
@@ -5049,20 +5001,17 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
   }
   llvm::omp::Directive dir{GetContext().directive};
 
-  if (OmpVerifyModifiers(deviceClause, llvm::omp::OMPC_device,
-          GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(deviceClause)};
+  auto &modifiers{OmpGetModifiers(deviceClause)};
 
-    if (auto *deviceMod{
-            OmpGetUniqueModifier<parser::OmpDeviceModifier>(modifiers)}) {
-      using Value = parser::OmpDeviceModifier::Value;
-      if (dir != llvm::omp::OMPD_target && deviceMod->v == Value::Ancestor) {
-        auto name{llvm::omp::getDescriptor(llvm::omp::Modifier::DeviceModifier)
-                .getName()};
-        context_.Say(OmpGetModifierSource(modifiers, deviceMod),
-            "The ANCESTOR %s must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on %s construct."_err_en_US,
-            name.str(), parser::omp::GetUpperName(dir, version));
-      }
+  if (auto *deviceMod{
+          OmpGetUniqueModifier<parser::OmpDeviceModifier>(modifiers)}) {
+    using Value = parser::OmpDeviceModifier::Value;
+    if (dir != llvm::omp::OMPD_target && deviceMod->v == Value::Ancestor) {
+      auto name{llvm::omp::getDescriptor(llvm::omp::Modifier::DeviceModifier)
+              .getName()};
+      context_.Say(OmpGetModifierSource(modifiers, deviceMod),
+          "The ANCESTOR %s must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on %s construct."_err_en_US,
+          name.str(), parser::omp::GetUpperName(dir, version));
     }
   }
 }
@@ -5141,14 +5090,11 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
         }
       }
     }
-    if (OmpVerifyModifiers(*taskDep, llvm::omp::OMPC_depend,
-            GetContext().clauseSource, context_)) {
-      auto &modifiers{OmpGetModifiers(*taskDep)};
-      if (OmpGetUniqueModifier<parser::OmpIterator>(modifiers)) {
-        if (dir == llvm::omp::OMPD_depobj) {
-          context_.Say(GetContext().clauseSource,
-              "An iterator-modifier may specify multiple locators, a DEPEND clause on a DEPOBJ construct must only specify one locator"_warn_en_US);
-        }
+    auto &modifiers{OmpGetModifiers(*taskDep)};
+    if (OmpGetUniqueModifier<parser::OmpIterator>(modifiers)) {
+      if (dir == llvm::omp::OMPD_depobj) {
+        context_.Say(GetContext().clauseSource,
+            "An iterator-modifier may specify multiple locators, a DEPEND clause on a DEPOBJ construct must only specify one locator"_warn_en_US);
       }
     }
   }
@@ -5160,12 +5106,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Doacross &x) {
 
 void OmpStructureChecker::CheckDoacross(
     const parser::OmpDoacross &doa, llvm::omp::Clause clauseId) {
-  parser::CharBlock clauseSource{GetContext().clauseSource};
-
-  if (!OmpVerifyModifiers(doa, clauseId, clauseSource, context_)) {
-    return;
-  }
-
   auto &iterVec{std::get<std::optional<parser::OmpIterationVector>>(doa.t)};
 
   auto &modifiers{OmpGetModifiers(doa)};
@@ -5298,61 +5238,58 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
   CheckPrivateSymbolsInOuterCxt(
       currSymbols, dirClauseTriple, llvm::omp::Clause::OMPC_lastprivate);
 
-  if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_lastprivate,
-          GetContext().clauseSource, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    using LastprivateModifier = parser::OmpLastprivateModifier;
-    if (auto *modifier{OmpGetUniqueModifier<LastprivateModifier>(modifiers)}) {
-      CheckLastprivateModifier(*modifier);
-      if (modifier->v == LastprivateModifier::Value::Conditional) {
-        // A conditional lastprivate list item must be a scalar variable of
-        // intrinsic Numeric or Logical category.  Arrays are excluded by the
-        // rank check; character, derived, and polymorphic entities by the
-        // category check.
-        auto checkConditionalItem{[&](const Symbol &symbol,
-                                      const parser::CharBlock &source) {
-          // Resolve host/use-association so the type and attribute checks see
-          // the entity's real properties, not the local association symbol.
-          const Symbol &ultimate{symbol.GetUltimate()};
-          const DeclTypeSpec *type{ultimate.GetType()};
-          bool isScalarIntrinsicNonChar{ultimate.Rank() == 0 && type &&
-              (type->category() == DeclTypeSpec::Category::Numeric ||
-                  type->category() == DeclTypeSpec::Category::Logical)};
-          if (!isScalarIntrinsicNonChar) {
-            context_.Say(source,
-                "A list item that appears in a LASTPRIVATE clause with the "
-                "CONDITIONAL modifier must be a scalar variable with intrinsic "
-                "type, as defined by the Fortran language, excluding character "
-                "type, but '%s' is not"_err_en_US,
-                symbol.name());
-          } else if (IsAllocatableOrPointer(ultimate)) {
-            // Standard-legal, but lowering does not yet preserve descriptors.
-            // TODO: support POINTER/ALLOCATABLE conditional lastprivate.
-            context_.Say(source,
-                "A POINTER or ALLOCATABLE list item is not yet supported by "
-                "Flang in a LASTPRIVATE clause with the CONDITIONAL modifier, "
-                "'%s'"_err_en_US,
-                symbol.name());
-          }
-        }};
-        // Check whole variables (Designator -> DataRef -> Name) and
-        // common blocks (a bare Name, rejected above as having no type).
-        // Array elements, sections, components, and substrings are other
-        // designator forms, left to the general OpenMP object diagnostics.
-        for (const parser::OmpObject &object : objectList.v) {
-          const parser::Name *name{std::get_if<parser::Name>(&object.u)};
-          if (!name) {
-            if (const auto *designator{
-                    std::get_if<parser::Designator>(&object.u)}) {
-              if (const auto *dataRef{
-                      std::get_if<parser::DataRef>(&designator->u)}) {
-                name = std::get_if<parser::Name>(&dataRef->u);
-              }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  using LastprivateModifier = parser::OmpLastprivateModifier;
+  if (auto *modifier{OmpGetUniqueModifier<LastprivateModifier>(modifiers)}) {
+    CheckLastprivateModifier(*modifier);
+    if (modifier->v == LastprivateModifier::Value::Conditional) {
+      // A conditional lastprivate list item must be a scalar variable of
+      // intrinsic Numeric or Logical category.  Arrays are excluded by the
+      // rank check; character, derived, and polymorphic entities by the
+      // category check.
+      auto checkConditionalItem{[&](const Symbol &symbol,
+                                    const parser::CharBlock &source) {
+        // Resolve host/use-association so the type and attribute checks see
+        // the entity's real properties, not the local association symbol.
+        const Symbol &ultimate{symbol.GetUltimate()};
+        const DeclTypeSpec *type{ultimate.GetType()};
+        bool isScalarIntrinsicNonChar{ultimate.Rank() == 0 && type &&
+            (type->category() == DeclTypeSpec::Category::Numeric ||
+                type->category() == DeclTypeSpec::Category::Logical)};
+        if (!isScalarIntrinsicNonChar) {
+          context_.Say(source,
+              "A list item that appears in a LASTPRIVATE clause with the "
+              "CONDITIONAL modifier must be a scalar variable with intrinsic "
+              "type, as defined by the Fortran language, excluding character "
+              "type, but '%s' is not"_err_en_US,
+              symbol.name());
+        } else if (IsAllocatableOrPointer(ultimate)) {
+          // Standard-legal, but lowering does not yet preserve descriptors.
+          // TODO: support POINTER/ALLOCATABLE conditional lastprivate.
+          context_.Say(source,
+              "A POINTER or ALLOCATABLE list item is not yet supported by "
+              "Flang in a LASTPRIVATE clause with the CONDITIONAL modifier, "
+              "'%s'"_err_en_US,
+              symbol.name());
+        }
+      }};
+      // Check whole variables (Designator -> DataRef -> Name) and
+      // common blocks (a bare Name, rejected above as having no type).
+      // Array elements, sections, components, and substrings are other
+      // designator forms, left to the general OpenMP object diagnostics.
+      for (const parser::OmpObject &object : objectList.v) {
+        const parser::Name *name{std::get_if<parser::Name>(&object.u)};
+        if (!name) {
+          if (const auto *designator{
+                  std::get_if<parser::Designator>(&object.u)}) {
+            if (const auto *dataRef{
+                    std::get_if<parser::DataRef>(&designator->u)}) {
+              name = std::get_if<parser::Name>(&dataRef->u);
             }
           }
-          if (name && name->symbol) {
-            checkConditionalItem(*name->symbol, name->source);
-          }
+        }
+        if (name && name->symbol) {
+          checkConditionalItem(*name->symbol, name->source);
         }
       }
     }
@@ -5617,16 +5554,6 @@ void OmpStructureChecker::CheckUsesAllocatorsSpec(
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
   bool isLegacySyntax{std::get<bool>(spec.t)};
 
-  // The traits of the deprecated syntax are stored as a traits-array modifier,
-  // but they are not the 5.2 modifier, so they must not be version-checked.
-  // A modifier that postdates the OpenMP version in effect is only warned
-  // about, so the specification is accepted as an extension and must still be
-  // checked, otherwise a malformed one would reach lowering unvalidated.
-  if (!isLegacySyntax) {
-    OmpVerifyModifiers(spec, llvm::omp::OMPC_uses_allocators,
-        GetContext().clauseSource, context_);
-  }
-
   auto &modifiers{OmpGetModifiers(spec)};
   const auto *memSpace{OmpGetUniqueModifier<parser::OmpMemSpace>(modifiers)};
   const auto *traits{OmpGetUniqueModifier<parser::OmpTraitsArray>(modifiers)};
@@ -5898,17 +5825,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) {
   }
 }
 
-void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) {
-  OmpVerifyModifiers(
-      x.v, llvm::omp::OMPC_enter, GetContext().clauseSource, context_);
-}
-
 void OmpStructureChecker::Enter(const parser::OmpClause::From &x) {
-  if (!OmpVerifyModifiers(
-          x.v, llvm::omp::OMPC_from, GetContext().clauseSource, context_)) {
-    return;
-  }
-
   auto &modifiers{OmpGetModifiers(x.v)};
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
 
@@ -5927,11 +5844,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::From &x) {
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::To &x) {
-  if (!OmpVerifyModifiers(
-          x.v, llvm::omp::OMPC_to, GetContext().clauseSource, context_)) {
-    return;
-  }
-
   auto &modifiers{OmpGetModifiers(x.v)};
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
 
@@ -6436,15 +6348,12 @@ void OmpStructureChecker::CheckDimsModifier(parser::CharBlock source,
 
 void OmpStructureChecker::Enter(const parser::OmpClause::NumTeams &x) {
   constexpr auto clauseId{llvm::omp::Clause::OMPC_num_teams};
-  parser::CharBlock source{GetContext().clauseSource};
   auto &values{std::get<std::list<parser::ScalarIntExpr>>(x.v.t)};
 
-  if (OmpVerifyModifiers(x.v, clauseId, source, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
-      CheckDimsModifier(
-          OmpGetModifierSource(modifiers, dims), values.size(), *dims);
-    }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
+    CheckDimsModifier(
+        OmpGetModifierSource(modifiers, dims), values.size(), *dims);
   }
 
   for (auto &val : values) {
@@ -6454,15 +6363,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::NumTeams &x) {
 
 void OmpStructureChecker::Enter(const parser::OmpClause::NumThreads &x) {
   constexpr auto clauseId{llvm::omp::Clause::OMPC_num_threads};
-  parser::CharBlock source{GetContext().clauseSource};
   auto &values{std::get<std::list<parser::ScalarIntExpr>>(x.v.t)};
 
-  if (OmpVerifyModifiers(x.v, clauseId, source, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
-      CheckDimsModifier(
-          OmpGetModifierSource(modifiers, dims), values.size(), *dims);
-    }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
+    CheckDimsModifier(
+        OmpGetModifierSource(modifiers, dims), values.size(), *dims);
   }
 
   for (auto &val : values) {
@@ -6472,15 +6378,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::NumThreads &x) {
 
 void OmpStructureChecker::Enter(const parser::OmpClause::ThreadLimit &x) {
   constexpr auto clauseId{llvm::omp::Clause::OMPC_thread_limit};
-  parser::CharBlock source{GetContext().clauseSource};
   auto &values{std::get<std::list<parser::ScalarIntExpr>>(x.v.t)};
 
-  if (OmpVerifyModifiers(x.v, clauseId, source, context_)) {
-    auto &modifiers{OmpGetModifiers(x.v)};
-    if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
-      CheckDimsModifier(
-          OmpGetModifierSource(modifiers, dims), values.size(), *dims);
-    }
+  auto &modifiers{OmpGetModifiers(x.v)};
+  if (auto *dims{OmpGetUniqueModifier<parser::OmpDimsModifier>(modifiers)}) {
+    CheckDimsModifier(
+        OmpGetModifierSource(modifiers, dims), values.size(), *dims);
   }
 
   for (auto &val : values) {
@@ -6575,58 +6478,50 @@ void OmpStructureChecker::Enter(const parser::OpenMPInteropConstruct &x) {
             [&](const parser::OmpClause::Init &initClause) {
               hasInitClause = true;
               hasActionClause = true;
-              if (OmpVerifyModifiers(initClause.v, llvm::omp::OMPC_init,
-                      GetContext().directiveSource, context_)) {
-
-                auto &modifiers{OmpGetModifiers(initClause.v)};
-                auto &&interopTypeModifier{
-                    OmpGetRepeatableModifier<parser::OmpInteropType>(
-                        modifiers)};
-                for (const auto &it : interopTypeModifier) {
-                  if (it->v == parser::OmpInteropType::Value::Targetsync) {
-                    ++targetSyncCount;
-                  } else {
-                    ++targetCount;
-                  }
+              auto &modifiers{OmpGetModifiers(initClause.v)};
+              auto &&interopTypeModifier{
+                  OmpGetRepeatableModifier<parser::OmpInteropType>(modifiers)};
+              for (const auto &it : interopTypeModifier) {
+                if (it->v == parser::OmpInteropType::Value::Targetsync) {
+                  ++targetSyncCount;
+                } else {
+                  ++targetCount;
                 }
-                if (auto *depInfo{
-                        OmpGetUniqueModifier<parser::OmpDepinfoModifier>(
-                            modifiers)}) {
-                  auto &desc{llvm::omp::getDescriptor(
-                      llvm::omp::Modifier::DepinfoModifier)};
-                  context_.Say(OmpGetModifierSource(modifiers, depInfo),
-                      "The '%s' is not allowed on INTEROP construct"_err_en_US,
-                      desc.getName().str());
-                }
-                // A prefer_type foreign-runtime-identifier must be a
-                // constant expression of integer OpenMP type or a base
-                // language string literal. This is enforced for the flat form
-                // (prefer_type(fr-id, ...)); the OpenMP 6.0
-                // brace form (prefer_type({fr(...), attr(...)}, ...)) is not
-                // yet supported in lowering and is diagnosed there, so its
-                // operands are not validated here.
-                if (auto *preferType{
-                        OmpGetUniqueModifier<parser::OmpPreferType>(
-                            modifiers)}) {
-                  for (const auto &prefSpec : preferType->v) {
-                    const auto *fri{
-                        std::get_if<parser::OmpPreferenceSpecification::
-                                ForeignRuntimeIdentifier>(&prefSpec.u)};
-                    if (!fri) {
-                      continue;
-                    }
-                    if (const auto *expr{GetExpr(context_, fri->value())}) {
-                      std::optional<evaluate::DynamicType> type{
-                          expr->GetType()};
-                      bool isIntOrChar{type &&
-                          (type->category() ==
-                                  evaluate::TypeCategory::Integer ||
-                              type->category() ==
-                                  evaluate::TypeCategory::Character)};
-                      if (!evaluate::IsConstantExpr(*expr) || !isIntOrChar) {
-                        context_.Say(fri->value().source,
-                            "The foreign-runtime-identifier in a `prefer_type` modifier must be a constant expression of integer OpenMP type or a base language string literal"_err_en_US);
-                      }
+              }
+              if (auto *depInfo{
+                      OmpGetUniqueModifier<parser::OmpDepinfoModifier>(
+                          modifiers)}) {
+                auto &desc{llvm::omp::getDescriptor(
+                    llvm::omp::Modifier::DepinfoModifier)};
+                context_.Say(OmpGetModifierSource(modifiers, depInfo),
+                    "The '%s' is not allowed on INTEROP construct"_err_en_US,
+                    desc.getName().str());
+              }
+              // A prefer_type foreign-runtime-identifier must be a
+              // constant expression of integer OpenMP type or a base
+              // language string literal. This is enforced for the flat form
+              // (prefer_type(fr-id, ...)); the OpenMP 6.0
+              // brace form (prefer_type({fr(...), attr(...)}, ...)) is not
+              // yet supported in lowering and is diagnosed there, so its
+              // operands are not validated here.
+              if (auto *preferType{
+                      OmpGetUniqueModifier<parser::OmpPreferType>(modifiers)}) {
+                for (const auto &prefSpec : preferType->v) {
+                  const auto *fri{
+                      std::get_if<parser::OmpPreferenceSpecification::
+                              ForeignRuntimeIdentifier>(&prefSpec.u)};
+                  if (!fri) {
+                    continue;
+                  }
+                  if (const auto *expr{GetExpr(context_, fri->value())}) {
+                    std::optional<evaluate::DynamicType> type{expr->GetType()};
+                    bool isIntOrChar{type &&
+                        (type->category() == evaluate::TypeCategory::Integer ||
+                            type->category() ==
+                                evaluate::TypeCategory::Character)};
+                    if (!evaluate::IsConstantExpr(*expr) || !isIntOrChar) {
+                      context_.Say(fri->value().source,
+                          "The foreign-runtime-identifier in a `prefer_type` modifier must be a constant expression of integer OpenMP type or a base language string literal"_err_en_US);
                     }
                   }
                 }

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 6a19363dd1bd6..c3ac73935f4df 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -220,8 +220,6 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
   void Enter(const parser::OmpClause::Device &x);
   void Enter(const parser::OmpClause::Doacross &x);
   void Enter(const parser::OmpClause::DynamicAllocators &x);
-  void Enter(const parser::OmpClause::DynGroupprivate &x);
-  void Enter(const parser::OmpClause::Enter &x);
   void Enter(const parser::OmpClause::Firstprivate &x);
   void Enter(const parser::OmpClause::From &x);
   void Enter(const parser::OmpClause::HasDeviceAddr &x);

diff  --git a/flang/lib/Semantics/check-omp-variant.cpp b/flang/lib/Semantics/check-omp-variant.cpp
index 2e747408cec87..d4372897b84a4 100644
--- a/flang/lib/Semantics/check-omp-variant.cpp
+++ b/flang/lib/Semantics/check-omp-variant.cpp
@@ -187,13 +187,11 @@ void OmpStructureChecker::CheckDefaultNoneInAssociatedLoop(
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::When &x) {
-  OmpVerifyModifiers(
-      x.v, llvm::omp::OMPC_when, GetContext().clauseSource, context_);
   // Record this WHEN clause's context selector so the variant directive it
   // controls can be paired with it for static-applicability matching. A
   // well-formed WHEN clause has exactly one modifier, its context selector;
   // pair it only in that case, which also makes front() safe. Any other count
-  // is malformed and already diagnosed by OmpVerifyModifiers above.
+  // is malformed and already diagnosed by VerifyModifiers.
   if (const auto &modifiers{std::get<0>(x.v.t)};
       modifiers && modifiers->size() == 1) {
     currentWhenSelector_ =


        


More information about the flang-commits mailing list