[flang-commits] [flang] [flang][Semantics][OpenMP] Check type of reduction variables (PR #94596)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Jun 6 12:34:12 PDT 2024


================
@@ -2378,6 +2378,89 @@ bool OmpStructureChecker::CheckIntrinsicOperator(
   return false;
 }
 
+static bool isReductionAllowedForType(
+    const parser::OmpClause::Reduction &x, const DeclTypeSpec *type) {
+  assert(type && "no type for reduction symbol");
+  const auto &definedOp{std::get<parser::OmpReductionOperator>(x.v.t)};
+  // TODO: user defined reduction operators. Just allow everything for now.
+  bool ok{true};
+
+  auto isLogical = [](const DeclTypeSpec *type) -> bool {
+    return type->category() == DeclTypeSpec::Logical;
+  };
+  auto isCharacter = [](const DeclTypeSpec *type) -> bool {
+    return type->category() == DeclTypeSpec::Character;
+  };
+
+  common::visit(
+      common::visitors{
+          [&](const parser::DefinedOperator &dOpr) {
+            if (const auto *intrinsicOp{
+                    std::get_if<parser::DefinedOperator::IntrinsicOperator>(
+                        &dOpr.u)}) {
+              // OMP5.2: The type [...] of a list item that appears in a
+              // reduction clause must be valid for the combiner expression
+              // See F2023: Table 10.2
+              // .LT., .LE., .GT., .GE. are handled as procedure designators
+              // below.
+              switch (*intrinsicOp) {
+              case parser::DefinedOperator::IntrinsicOperator::Multiply:
+                [[fallthrough]];
+              case parser::DefinedOperator::IntrinsicOperator::Add:
+                [[fallthrough]];
+              case parser::DefinedOperator::IntrinsicOperator::Subtract:
+                ok = type->IsNumeric(TypeCategory::Integer) ||
+                    type->IsNumeric(TypeCategory::Real) ||
+                    type->IsNumeric(TypeCategory::Complex);
+                break;
+
+              case parser::DefinedOperator::IntrinsicOperator::AND:
+                [[fallthrough]];
+              case parser::DefinedOperator::IntrinsicOperator::OR:
+                [[fallthrough]];
+              case parser::DefinedOperator::IntrinsicOperator::EQV:
+                [[fallthrough]];
+              case parser::DefinedOperator::IntrinsicOperator::NEQV:
+                ok = isLogical(type);
+                break;
+
+              // Reduction identifier is not in OMP5.2 Table 5.2
+              default:
+                assert(false &&
+                    "This should have been caught in CheckIntrinsicOperator");
+                ok = false;
+                break;
+              }
+            }
+          },
+          [&](const parser::ProcedureDesignator &procD) {
----------------
klausler wrote:

So long as a procedure component or procedure binding is caught as an error somewhere in semantics, it doesn't need to be a parsing issue.  A `parser::Name` wouldn't be enough, I don't think, because operators are also acceptable.  If procedure components or procedure bindings are not caught in semantics, I suggest defining a new parse tree node and corresponding parser that are limited to what is allowed to appear only.

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


More information about the flang-commits mailing list