diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index cef57f1851bcc..212356136d6ee 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -1402,10 +1402,8 @@ using OperatorSet = common::EnumSet; std::string ToString(Operator op); -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - switch (op.derived().logicalOperator) { +template Operator OperationCode(const LogicalOperation &op) { + switch (op.logicalOperator) { case common::LogicalOperator::And: return Operator::And; case common::LogicalOperator::Or: @@ -1420,10 +1418,10 @@ Operator OperationCode( return Operator::Unknown; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - switch (op.derived().opr) { +Operator OperationCode(const Relational &op); + +template Operator OperationCode(const Relational &op) { + switch (op.opr) { case common::RelationalOperator::LT: return Operator::Lt; case common::RelationalOperator::LE: @@ -1440,44 +1438,32 @@ Operator OperationCode( return Operator::Unknown; } -template -Operator OperationCode(const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Add &op) { return Operator::Add; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Subtract &op) { return Operator::Sub; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Multiply &op) { return Operator::Mul; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Divide &op) { return Operator::Div; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const Power &op) { return Operator::Pow; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template Operator OperationCode(const RealToIntPower &op) { return Operator::Pow; } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { +template +Operator OperationCode(const Convert &op) { if constexpr (C == T::category) { return Operator::Resize; } else { @@ -1485,25 +1471,27 @@ Operator OperationCode( } } -template -Operator OperationCode( - const evaluate::Operation, Ts...> &op) { - if (op.derived().ordering == evaluate::Ordering::Greater) { +template Operator OperationCode(const Extremum &op) { + if (op.ordering == Ordering::Greater) { return Operator::Max; } else { return Operator::Min; } } -template Operator OperationCode(const evaluate::Constant &x) { +template Operator OperationCode(const Constant &x) { return Operator::Constant; } +template Operator OperationCode(const Designator &x) { + return Operator::Identity; +} + template Operator OperationCode(const T &) { return Operator::Unknown; } -Operator OperationCode(const evaluate::ProcedureDesignator &proc); +Operator OperationCode(const ProcedureDesignator &proc); } // namespace operation diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 171dd91fa9fd1..9c059b08dd41c 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1693,17 +1693,17 @@ struct ArgumentExtractor // to int(kind=4) for example. return (*this)(x.template operand<0>()); } else { - return std::make_pair(operation::OperationCode(x), + return std::make_pair(operation::OperationCode(x.derived()), OperationArgs(x, std::index_sequence_for{})); } } template Result operator()(const Designator &x) const { - return {operation::Operator::Identity, {AsSomeExpr(x)}}; + return {operation::OperationCode(x), {AsSomeExpr(x)}}; } template Result operator()(const Constant &x) const { - return {operation::Operator::Identity, {AsSomeExpr(x)}}; + return {operation::OperationCode(x), {AsSomeExpr(x)}}; } template @@ -1793,6 +1793,10 @@ std::string operation::ToString(operation::Operator op) { llvm_unreachable("Unhandler operator"); } +operation::Operator operation::OperationCode(const Relational &op) { + return common::visit([](auto &&s) { return OperationCode(s); }, op.u); +} + operation::Operator operation::OperationCode(const ProcedureDesignator &proc) { Operator code{llvm::StringSwitch(proc.GetName()) .Case("associated", Operator::Associated) diff --git a/flang/test/Semantics/OpenMP/atomic04.f90 b/flang/test/Semantics/OpenMP/atomic04.f90 index fb87ca5186612..8f8af31245404 100644 --- a/flang/test/Semantics/OpenMP/atomic04.f90 +++ b/flang/test/Semantics/OpenMP/atomic04.f90 @@ -180,7 +180,7 @@ subroutine more_invalid_atomic_update_stmts() x = x !$omp atomic update - !ERROR: The atomic variable x should appear as an argument in the update operation + !ERROR: This is not a valid ATOMIC UPDATE operation x = 1 !$omp atomic update diff --git a/flang/test/Semantics/OpenMP/atomic05.f90 b/flang/test/Semantics/OpenMP/atomic05.f90 index 77ffc6e57f1a3..e0103be4cae4a 100644 --- a/flang/test/Semantics/OpenMP/atomic05.f90 +++ b/flang/test/Semantics/OpenMP/atomic05.f90 @@ -19,7 +19,7 @@ program OmpAtomic x = 2 * 4 !ERROR: At most one clause from the 'memory-order' group is allowed on ATOMIC construct !$omp atomic update release, seq_cst - !ERROR: The atomic variable x should appear as an argument in the update operation + !ERROR: This is not a valid ATOMIC UPDATE operation x = 10 !ERROR: At most one clause from the 'memory-order' group is allowed on ATOMIC construct !$omp atomic capture release, seq_cst