@@ -420,13 +420,47 @@ void OmpStructureChecker::HasInvalidDistributeNesting(
420420 " region." _err_en_US);
421421 }
422422}
423+ void OmpStructureChecker::HasInvalidLoopBinding (
424+ const parser::OpenMPLoopConstruct &x) {
425+ const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t )};
426+ const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t )};
427+
428+ auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
429+ const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t )};
430+ for (const auto &clause : clauseList.v ) {
431+ if (const auto *bindClause{
432+ std::get_if<parser::OmpClause::Bind>(&clause.u )}) {
433+ if (bindClause->v .v != parser::OmpBindClause::Type::Teams) {
434+ context_.Say (beginDir.source , msg);
435+ }
436+ }
437+ }
438+ };
439+
440+ if (llvm::omp::Directive::OMPD_loop == beginDir.v &&
441+ CurrentDirectiveIsNested () &&
442+ OmpDirectiveSet{llvm::omp::OMPD_teams, llvm::omp::OMPD_target_teams}.test (
443+ GetContextParent ().directive )) {
444+ teamsBindingChecker (
445+ " `BIND(TEAMS)` must be specified since the `LOOP` region is "
446+ " strictly nested inside a `TEAMS` region." _err_en_US);
447+ }
448+
449+ if (OmpDirectiveSet{
450+ llvm::omp::OMPD_teams_loop, llvm::omp::OMPD_target_teams_loop}
451+ .test (beginDir.v )) {
452+ teamsBindingChecker (
453+ " `BIND(TEAMS)` must be specified since the `LOOP` directive is "
454+ " combined with a `TEAMS` construct." _err_en_US);
455+ }
456+ }
423457
424458void OmpStructureChecker::HasInvalidTeamsNesting (
425459 const llvm::omp::Directive &dir, const parser::CharBlock &source) {
426460 if (!llvm::omp::nestedTeamsAllowedSet.test (dir)) {
427461 context_.Say (source,
428- " Only `DISTRIBUTE` or `PARALLEL ` regions are allowed to be strictly "
429- " nested inside `TEAMS` region." _err_en_US);
462+ " Only `DISTRIBUTE`, `PARALLEL`, or `LOOP ` regions are allowed to be "
463+ " strictly nested inside `TEAMS` region." _err_en_US);
430464 }
431465}
432466
@@ -589,6 +623,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
589623 CheckLoopItrVariableIsInt (x);
590624 CheckAssociatedLoopConstraints (x);
591625 HasInvalidDistributeNesting (x);
626+ HasInvalidLoopBinding (x);
592627 if (CurrentDirectiveIsNested () &&
593628 llvm::omp::topTeamsSet.test (GetContextParent ().directive )) {
594629 HasInvalidTeamsNesting (beginDir.v , beginDir.source );
0 commit comments