@@ -588,50 +588,52 @@ void OmpStructureChecker::CheckNestedFuse(
588588 }
589589}
590590
591+ void OmpStructureChecker::CheckScanModifier (
592+ const parser::OmpClause::Reduction &x) {
593+ using ReductionModifier = parser::OmpReductionModifier;
594+
595+ auto checkReductionSymbolInScan{[&](const parser::Name &name) {
596+ if (auto *symbol{name.symbol }) {
597+ if (!symbol->test (Symbol::Flag::OmpInclusiveScan) &&
598+ !symbol->test (Symbol::Flag::OmpExclusiveScan)) {
599+ context_.Say (name.source ,
600+ " List item %s must appear in EXCLUSIVE or INCLUSIVE clause of an enclosed SCAN directive" _err_en_US,
601+ name.ToString ());
602+ }
603+ }
604+ }};
605+
606+ auto &modifiers{OmpGetModifiers (x.v )};
607+ auto *maybeModifier{OmpGetUniqueModifier<ReductionModifier>(modifiers)};
608+ if (maybeModifier && maybeModifier->v == ReductionModifier::Value::Inscan) {
609+ for (const auto &ompObj : parser::omp::GetOmpObjectList (x)->v ) {
610+ common::visit (
611+ common::visitors{
612+ [&](const parser::Designator &desg) {
613+ if (auto *name{parser::GetDesignatorNameIfDataRef (desg)}) {
614+ checkReductionSymbolInScan (*name);
615+ }
616+ },
617+ [&](const parser::Name &name) {
618+ checkReductionSymbolInScan (name);
619+ },
620+ [&](const parser::OmpObject::Invalid &invalid) {},
621+ },
622+ ompObj.u );
623+ }
624+ }
625+ }
626+
591627void OmpStructureChecker::Leave (const parser::OpenMPLoopConstruct &x) {
592628 const parser::OmpClauseList &clauseList{x.BeginDir ().Clauses ()};
593629
594630 // A few semantic checks for InScan reduction are performed below as SCAN
595631 // constructs inside LOOP may add the relevant information. Scan reduction is
596632 // supported only in loop constructs, so same checks are not applicable to
597633 // other directives.
598- using ReductionModifier = parser::OmpReductionModifier;
599634 for (const auto &clause : clauseList.v ) {
600- if (const auto *reductionClause{
601- std::get_if<parser::OmpClause::Reduction>(&clause.u )}) {
602- auto &modifiers{OmpGetModifiers (reductionClause->v )};
603- auto *maybeModifier{OmpGetUniqueModifier<ReductionModifier>(modifiers)};
604- if (maybeModifier &&
605- maybeModifier->v == ReductionModifier::Value::Inscan) {
606- auto checkReductionSymbolInScan = [&](const parser::Name *name) {
607- if (auto &symbol = name->symbol ) {
608- if (!symbol->test (Symbol::Flag::OmpInclusiveScan) &&
609- !symbol->test (Symbol::Flag::OmpExclusiveScan)) {
610- context_.Say (name->source ,
611- " List item %s must appear in EXCLUSIVE or "
612- " INCLUSIVE clause of an "
613- " enclosed SCAN directive" _err_en_US,
614- name->ToString ());
615- }
616- }
617- };
618- for (const auto &ompObj : parser::omp::GetOmpObjectList (clause)->v ) {
619- common::visit (
620- common::visitors{
621- [&](const parser::Designator &designator) {
622- if (const auto *name{
623- parser::GetDesignatorNameIfDataRef (designator)}) {
624- checkReductionSymbolInScan (name);
625- }
626- },
627- [&](const parser::Name &name) {
628- checkReductionSymbolInScan (&name);
629- },
630- [&](const parser::OmpObject::Invalid &invalid) {},
631- },
632- ompObj.u );
633- }
634- }
635+ if (auto *reduction{std::get_if<parser::OmpClause::Reduction>(&clause.u )}) {
636+ CheckScanModifier (*reduction);
635637 }
636638 }
637639 if (llvm::omp::allSimdSet.test (GetContext ().directive )) {
0 commit comments