@@ -369,13 +369,47 @@ void OmpStructureChecker::HasInvalidDistributeNesting(
369369 " region." _err_en_US);
370370 }
371371}
372+ void OmpStructureChecker::HasInvalidLoopBinding (
373+ const parser::OpenMPLoopConstruct &x) {
374+ const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t )};
375+ const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t )};
376+
377+ auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
378+ const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t )};
379+ for (const auto &clause : clauseList.v ) {
380+ if (const auto *bindClause{
381+ std::get_if<parser::OmpClause::Bind>(&clause.u )}) {
382+ if (bindClause->v .v != parser::OmpBindClause::Type::Teams) {
383+ context_.Say (beginDir.source , msg);
384+ }
385+ }
386+ }
387+ };
388+
389+ if (llvm::omp::Directive::OMPD_loop == beginDir.v &&
390+ CurrentDirectiveIsNested () &&
391+ OmpDirectiveSet{llvm::omp::OMPD_teams, llvm::omp::OMPD_target_teams}.test (
392+ GetContextParent ().directive )) {
393+ teamsBindingChecker (
394+ " `BIND(TEAMS)` must be specified since the `LOOP` region is "
395+ " strictly nested inside a `TEAMS` region." _err_en_US);
396+ }
397+
398+ if (OmpDirectiveSet{
399+ llvm::omp::OMPD_teams_loop, llvm::omp::OMPD_target_teams_loop}
400+ .test (beginDir.v )) {
401+ teamsBindingChecker (
402+ " `BIND(TEAMS)` must be specified since the `LOOP` directive is "
403+ " combined with a `TEAMS` construct." _err_en_US);
404+ }
405+ }
372406
373407void OmpStructureChecker::HasInvalidTeamsNesting (
374408 const llvm::omp::Directive &dir, const parser::CharBlock &source) {
375409 if (!llvm::omp::nestedTeamsAllowedSet.test (dir)) {
376410 context_.Say (source,
377- " Only `DISTRIBUTE` or `PARALLEL ` regions are allowed to be strictly "
378- " nested inside `TEAMS` region." _err_en_US);
411+ " Only `DISTRIBUTE`, `PARALLEL`, or `LOOP ` regions are allowed to be "
412+ " strictly nested inside `TEAMS` region." _err_en_US);
379413 }
380414}
381415
@@ -538,6 +572,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
538572 CheckLoopItrVariableIsInt (x);
539573 CheckAssociatedLoopConstraints (x);
540574 HasInvalidDistributeNesting (x);
575+ HasInvalidLoopBinding (x);
541576 if (CurrentDirectiveIsNested () &&
542577 llvm::omp::topTeamsSet.test (GetContextParent ().directive )) {
543578 HasInvalidTeamsNesting (beginDir.v , beginDir.source );
0 commit comments