@@ -363,13 +363,47 @@ void OmpStructureChecker::HasInvalidDistributeNesting(
363363 " region." _err_en_US);
364364 }
365365}
366+ void OmpStructureChecker::HasInvalidLoopBinding (
367+ const parser::OpenMPLoopConstruct &x) {
368+ const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t )};
369+ const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t )};
370+
371+ auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
372+ const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t )};
373+ for (const auto &clause : clauseList.v ) {
374+ if (const auto *bindClause{
375+ std::get_if<parser::OmpClause::Bind>(&clause.u )}) {
376+ if (bindClause->v .v != parser::OmpBindClause::Type::Teams) {
377+ context_.Say (beginDir.source , msg);
378+ }
379+ }
380+ }
381+ };
382+
383+ if (llvm::omp::Directive::OMPD_loop == beginDir.v &&
384+ CurrentDirectiveIsNested () &&
385+ OmpDirectiveSet{llvm::omp::OMPD_teams, llvm::omp::OMPD_target_teams}.test (
386+ GetContextParent ().directive )) {
387+ teamsBindingChecker (
388+ " `BIND(TEAMS)` must be specified since the `LOOP` region is "
389+ " strictly nested inside a `TEAMS` region." _err_en_US);
390+ }
391+
392+ if (OmpDirectiveSet{
393+ llvm::omp::OMPD_teams_loop, llvm::omp::OMPD_target_teams_loop}
394+ .test (beginDir.v )) {
395+ teamsBindingChecker (
396+ " `BIND(TEAMS)` must be specified since the `LOOP` directive is "
397+ " combined with a `TEAMS` construct." _err_en_US);
398+ }
399+ }
366400
367401void OmpStructureChecker::HasInvalidTeamsNesting (
368402 const llvm::omp::Directive &dir, const parser::CharBlock &source) {
369403 if (!llvm::omp::nestedTeamsAllowedSet.test (dir)) {
370404 context_.Say (source,
371- " Only `DISTRIBUTE` or `PARALLEL ` regions are allowed to be strictly "
372- " nested inside `TEAMS` region." _err_en_US);
405+ " Only `DISTRIBUTE`, `PARALLEL`, or `LOOP ` regions are allowed to be "
406+ " strictly nested inside `TEAMS` region." _err_en_US);
373407 }
374408}
375409
@@ -532,6 +566,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
532566 CheckLoopItrVariableIsInt (x);
533567 CheckAssociatedLoopConstraints (x);
534568 HasInvalidDistributeNesting (x);
569+ HasInvalidLoopBinding (x);
535570 if (CurrentDirectiveIsNested () &&
536571 llvm::omp::topTeamsSet.test (GetContextParent ().directive )) {
537572 HasInvalidTeamsNesting (beginDir.v , beginDir.source );
0 commit comments