diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index a4af1ce5771a8..e6398a39d9791 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2865,45 +2865,41 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) { bool OmpStructureChecker::CheckReductionOperators( const parser::OmpClause::Reduction &x) { + bool ok = false; auto &modifiers{OmpGetModifiers(x.v)}; - const auto *definedOp{ - OmpGetUniqueModifier(modifiers)}; - if (!definedOp) { - return false; + if (const auto *ident{ + OmpGetUniqueModifier(modifiers)}) { + + auto visitOperator{[&](const parser::DefinedOperator &dOpr) { + if (const auto *intrinsicOp{ + std::get_if( + &dOpr.u)}) { + ok = CheckIntrinsicOperator(*intrinsicOp); + } else { + context_.Say(GetContext().clauseSource, + "Invalid reduction operator in REDUCTION clause."_err_en_US, + ContextDirectiveAsFortran()); + } + }}; + + auto visitDesignator{[&](const parser::ProcedureDesignator &procD) { + const parser::Name *name{std::get_if(&procD.u)}; + if (name && name->symbol) { + const SourceName &realName{name->symbol->GetUltimate().name()}; + if (realName == "max" || realName == "min" || realName == "iand" || + realName == "ior" || realName == "ieor") { + ok = true; + } + } + if (!ok) { + context_.Say(GetContext().clauseSource, + "Invalid reduction identifier in REDUCTION " + "clause."_err_en_US, + ContextDirectiveAsFortran()); + } + }}; + common::visit(common::visitors{visitOperator, visitDesignator}, ident->u); } - bool ok = false; - common::visit( - common::visitors{ - [&](const parser::DefinedOperator &dOpr) { - if (const auto *intrinsicOp{ - std::get_if( - &dOpr.u)}) { - ok = CheckIntrinsicOperator(*intrinsicOp); - } else { - context_.Say(GetContext().clauseSource, - "Invalid reduction operator in REDUCTION clause."_err_en_US, - ContextDirectiveAsFortran()); - } - }, - [&](const parser::ProcedureDesignator &procD) { - const parser::Name *name{std::get_if(&procD.u)}; - if (name && name->symbol) { - const SourceName &realName{name->symbol->GetUltimate().name()}; - if (realName == "max" || realName == "min" || - realName == "iand" || realName == "ior" || - realName == "ieor") { - ok = true; - } - } - if (!ok) { - context_.Say(GetContext().clauseSource, - "Invalid reduction identifier in REDUCTION " - "clause."_err_en_US, - ContextDirectiveAsFortran()); - } - }, - }, - definedOp->u); return ok; } diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index c75808a8963b3..107bd3b09019a 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -522,49 +522,47 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { const auto &objList{std::get(x.v.t)}; ResolveOmpObjectList(objList, Symbol::Flag::OmpReduction); - auto &modifiers{OmpGetModifiers(x.v)}; - if (!modifiers) { - return false; - } - - auto createDummyProcSymbol = [&](const parser::Name *name) { - // If name resolution failed, create a dummy symbol - const auto namePair{ - currScope().try_emplace(name->source, Attrs{}, ProcEntityDetails{})}; - auto &newSymbol{*namePair.first->second}; - if (context_.intrinsics().IsIntrinsic(name->ToString())) { - newSymbol.attrs().set(Attr::INTRINSIC); - } - name->symbol = &newSymbol; - }; + if (auto &modifiers{OmpGetModifiers(x.v)}) { + auto createDummyProcSymbol = [&](const parser::Name *name) { + // If name resolution failed, create a dummy symbol + const auto namePair{currScope().try_emplace( + name->source, Attrs{}, ProcEntityDetails{})}; + auto &newSymbol{*namePair.first->second}; + if (context_.intrinsics().IsIntrinsic(name->ToString())) { + newSymbol.attrs().set(Attr::INTRINSIC); + } + name->symbol = &newSymbol; + }; - for (auto &mod : *modifiers) { - if (!std::holds_alternative(mod.u)) { - continue; - } - auto &opr{std::get(mod.u)}; - if (auto *procD{parser::Unwrap(opr.u)}) { - if (auto *name{parser::Unwrap(procD->u)}) { - if (!name->symbol) { - if (!ResolveName(name)) { - createDummyProcSymbol(name); + for (auto &mod : *modifiers) { + if (!std::holds_alternative(mod.u)) { + continue; + } + auto &opr{std::get(mod.u)}; + if (auto *procD{parser::Unwrap(opr.u)}) { + if (auto *name{parser::Unwrap(procD->u)}) { + if (!name->symbol) { + if (!ResolveName(name)) { + createDummyProcSymbol(name); + } } } - } - if (auto *procRef{parser::Unwrap(procD->u)}) { - if (!procRef->v.thing.component.symbol) { - if (!ResolveName(&procRef->v.thing.component)) { - createDummyProcSymbol(&procRef->v.thing.component); + if (auto *procRef{ + parser::Unwrap(procD->u)}) { + if (!procRef->v.thing.component.symbol) { + if (!ResolveName(&procRef->v.thing.component)) { + createDummyProcSymbol(&procRef->v.thing.component); + } } } } } - } - using ReductionModifier = parser::OmpReductionModifier; - if (auto *maybeModifier{ - OmpGetUniqueModifier(modifiers)}) { - if (maybeModifier->v == ReductionModifier::Value::Inscan) { - ResolveOmpObjectList(objList, Symbol::Flag::OmpInScanReduction); + using ReductionModifier = parser::OmpReductionModifier; + if (auto *maybeModifier{ + OmpGetUniqueModifier(modifiers)}) { + if (maybeModifier->v == ReductionModifier::Value::Inscan) { + ResolveOmpObjectList(objList, Symbol::Flag::OmpInScanReduction); + } } } return false;