@@ -84,21 +84,34 @@ class OmpWorkshareBlockChecker {
84
84
parser::CharBlock source_;
85
85
};
86
86
87
- class OmpCycleAndExitChecker {
87
+ class AssociatedLoopChecker {
88
88
public:
89
- OmpCycleAndExitChecker (SemanticsContext &context, std::int64_t level)
89
+ AssociatedLoopChecker (SemanticsContext &context, std::int64_t level)
90
90
: context_{context}, level_{level} {}
91
91
92
92
template <typename T> bool Pre (const T &) { return true ; }
93
93
template <typename T> void Post (const T &) {}
94
94
95
95
bool Pre (const parser::DoConstruct &dc) {
96
96
level_--;
97
- const auto &constructName{std::get<0 >(std::get<0 >(dc.t ).statement .t )};
97
+ const auto &doStmt{
98
+ std::get<parser::Statement<parser::NonLabelDoStmt>>(dc.t )};
99
+ const auto &constructName{
100
+ std::get<std::optional<parser::Name>>(doStmt.statement .t )};
98
101
if (constructName) {
99
102
constructNamesAndLevels_.emplace (
100
103
constructName.value ().ToString (), level_);
101
104
}
105
+ if (level_ >= 0 ) {
106
+ if (dc.IsDoWhile ()) {
107
+ context_.Say (doStmt.source ,
108
+ " The associated loop of a loop-associated directive cannot be a DO WHILE." _err_en_US);
109
+ }
110
+ if (!dc.GetLoopControl ()) {
111
+ context_.Say (doStmt.source ,
112
+ " The associated loop of a loop-associated directive cannot be a DO without control." _err_en_US);
113
+ }
114
+ }
102
115
return true ;
103
116
}
104
117
@@ -450,9 +463,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
450
463
const auto &doBlock{std::get<parser::Block>(doConstruct->t )};
451
464
CheckNoBranching (doBlock, beginDir.v , beginDir.source );
452
465
}
453
- CheckDoWhile (x);
454
466
CheckLoopItrVariableIsInt (x);
455
- CheckCycleConstraints (x);
467
+ CheckAssociatedLoopConstraints (x);
456
468
HasInvalidDistributeNesting (x);
457
469
if (CurrentDirectiveIsNested () &&
458
470
llvm::omp::topTeamsSet.test (GetContextParent ().directive )) {
@@ -478,21 +490,6 @@ void OmpStructureChecker::SetLoopInfo(const parser::OpenMPLoopConstruct &x) {
478
490
}
479
491
}
480
492
}
481
- void OmpStructureChecker::CheckDoWhile (const parser::OpenMPLoopConstruct &x) {
482
- const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t )};
483
- const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t )};
484
- if (beginDir.v == llvm::omp::Directive::OMPD_do) {
485
- if (const auto &doConstruct{
486
- std::get<std::optional<parser::DoConstruct>>(x.t )}) {
487
- if (doConstruct.value ().IsDoWhile ()) {
488
- const auto &doStmt{std::get<parser::Statement<parser::NonLabelDoStmt>>(
489
- doConstruct.value ().t )};
490
- context_.Say (doStmt.source ,
491
- " The DO loop cannot be a DO WHILE with DO directive." _err_en_US);
492
- }
493
- }
494
- }
495
- }
496
493
497
494
void OmpStructureChecker::CheckLoopItrVariableIsInt (
498
495
const parser::OpenMPLoopConstruct &x) {
@@ -647,8 +644,8 @@ std::int64_t OmpStructureChecker::GetOrdCollapseLevel(
647
644
const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t )};
648
645
const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t )};
649
646
std::int64_t orderedCollapseLevel{1 };
650
- std::int64_t orderedLevel{0 };
651
- std::int64_t collapseLevel{0 };
647
+ std::int64_t orderedLevel{1 };
648
+ std::int64_t collapseLevel{1 };
652
649
653
650
for (const auto &clause : clauseList.v ) {
654
651
if (const auto *collapseClause{
@@ -672,10 +669,10 @@ std::int64_t OmpStructureChecker::GetOrdCollapseLevel(
672
669
return orderedCollapseLevel;
673
670
}
674
671
675
- void OmpStructureChecker::CheckCycleConstraints (
672
+ void OmpStructureChecker::CheckAssociatedLoopConstraints (
676
673
const parser::OpenMPLoopConstruct &x) {
677
674
std::int64_t ordCollapseLevel{GetOrdCollapseLevel (x)};
678
- OmpCycleAndExitChecker checker{context_, ordCollapseLevel};
675
+ AssociatedLoopChecker checker{context_, ordCollapseLevel};
679
676
parser::Walk (x, checker);
680
677
}
681
678
0 commit comments