[flang-commits] [flang] [Flang][OpenMP] Add some semantic checks for Linear clause (PR #111354)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Fri Dec 6 07:00:16 PST 2024


================
@@ -3542,16 +3557,98 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
 void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
   CheckAllowedClause(llvm::omp::Clause::OMPC_linear);
 
+  parser::CharBlock source{GetContext().clauseSource};
   // 2.7 Loop Construct Restriction
   if ((llvm::omp::allDoSet | llvm::omp::allSimdSet)
           .test(GetContext().directive)) {
     if (std::holds_alternative<parser::OmpLinearClause::WithModifier>(x.v.u)) {
-      context_.Say(GetContext().clauseSource,
+      context_.Say(source,
           "A modifier may not be specified in a LINEAR clause "
           "on the %s directive"_err_en_US,
           ContextDirectiveAsFortran());
+      return;
+    }
+  }
+
+  // OpenMP 5.2: Ordered clause restriction
+  if (const auto *clause{
+          FindClause(GetContext(), llvm::omp::Clause::OMPC_ordered)}) {
+    const auto &orderedClause{std::get<parser::OmpClause::Ordered>(clause->u)};
+    if (orderedClause.v) {
+      return;
     }
   }
+
+  auto checkForValidLinearClause_01 = [&](const parser::Name &name,
+                                          bool is_ref) {
+    std::string listItemName{name.ToString()};
+    if (!is_ref && !name.symbol->GetType()->IsNumeric(TypeCategory::Integer)) {
+      context_.Say(source,
+          "The list item `%s` specified with other than linear-modifier `REF`"
+          " must be of type INTEGER"_err_en_US,
+          listItemName);
+    }
+    if (GetContext().directive == llvm::omp::Directive::OMPD_declare_simd &&
+        !IsDummy(*name.symbol)) {
+      context_.Say(source,
+          "The list item `%s` must be a dummy argument"_err_en_US,
+          listItemName);
+    }
+    if (IsPointer(*name.symbol) ||
+        name.symbol->test(Symbol::Flag::CrayPointer)) {
+      context_.Say(source,
+          "The list item `%s` in a LINEAR clause must not be Cray Pointer "
+          "or a variable with POINTER attribute"_err_en_US,
+          listItemName);
+    }
+    if (FindCommonBlockContaining(*name.symbol)) {
+      context_.Say(source,
+          "'%s' is a common block name and must not appear in an "
+          "LINEAR clause"_err_en_US,
+          listItemName);
+    }
+  };
+
+  auto checkForValidLinearClause_02 =
+      [&](const parser::Name &name,
+          const parser::OmpLinearModifier::Value &modifierValue) {
+        std::string listItemName{name.ToString()};
+        checkForValidLinearClause_01(
+            name, (modifierValue == parser::OmpLinearModifier::Value::Ref));
+        if (modifierValue != parser::OmpLinearModifier::Value::Val &&
+            IsDummy(*name.symbol) && IsValue(*name.symbol)) {
+          context_.Say(source,
+              "The list item `%s` specified with the linear-modifier `REF` or "
+              "`UVAL` must be a dummy argument without `VALUE` attribute"_err_en_US,
+              listItemName);
+        }
+        if (modifierValue == parser::OmpLinearModifier::Value::Ref &&
+            !(IsAllocatable(*name.symbol) || IsAssumedShape(*name.symbol) ||
+                IsPolymorphic(*name.symbol))) {
+          context_.Say(source,
+              "The list item `%s` specified with the linear-modifier `REF` "
+              "must be polymorphic variable, assumed-shape array, or a variable"
+              " with the `ALLOCATABLE` attribute"_err_en_US,
+              listItemName);
+        }
+      };
+
+  // OpenMP 5.2: Linear clause Restrictions
+  common::visit(
+      common::visitors{
+          [&](const parser::OmpLinearClause::WithoutModifier &withoutModifier) {
+            for (const auto &name : withoutModifier.names)
+              if (name.symbol)
+                checkForValidLinearClause_01(name, false);
----------------
kparzysz wrote:

Yes

https://github.com/llvm/llvm-project/pull/111354


More information about the flang-commits mailing list