diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -272,6 +272,12 @@ void Post(const parser::Name &); + const parser::OmpClause *associatedClause{nullptr}; + void SetAssociatedClause(const parser::OmpClause &c) { + associatedClause = &c; + } + const parser::OmpClause *GetAssociatedClause() { return associatedClause; } + private: std::int64_t GetAssociatedLoopLevelFromClauses(const parser::OmpClauseList &); @@ -782,24 +788,30 @@ const parser::OmpClauseList &x) { std::int64_t orderedLevel{0}; std::int64_t collapseLevel{0}; + const parser::OmpClause *ordClause{nullptr}; + const parser::OmpClause *collClause{nullptr}; for (const auto &clause : x.v) { if (const auto *orderedClause{ std::get_if(&clause.u)}) { if (const auto v{EvaluateInt64(context_, orderedClause->v)}) { orderedLevel = *v; } + ordClause = &clause; } if (const auto *collapseClause{ std::get_if(&clause.u)}) { if (const auto v{EvaluateInt64(context_, collapseClause->v)}) { collapseLevel = *v; } + collClause = &clause; } } if (orderedLevel && (!collapseLevel || orderedLevel >= collapseLevel)) { + SetAssociatedClause(*ordClause); return orderedLevel; } else if (!orderedLevel && collapseLevel) { + SetAssociatedClause(*collClause); return collapseLevel; } // orderedLevel < collapseLevel is an error handled in structural checks return 1; // default is outermost loop @@ -845,7 +857,15 @@ const auto it{block.begin()}; loop = it != block.end() ? GetDoConstructIf(*it) : nullptr; } - CHECK(level == 0); + // CHECK(level == 0); + if (const auto *clause{GetAssociatedClause()}) { + if (level != 0) { + context_.Say(clause->source, + "The value of the parameter in the collapse or ordered clause must" + " not be larger than the number of nested loops" + " following the construct."_err_en_US); + } + } } bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) { diff --git a/flang/test/Semantics/omp-do-collapse-postivecases.f90 b/flang/test/Semantics/omp-do-collapse-postivecases.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-collapse-postivecases.f90 @@ -0,0 +1,36 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Collapse Clause Positive cases + +!DEF: /omp_docollapse MainProgram +program omp_docollapse + !DEF: /omp_docollapse/i ObjectEntity INTEGER(4) + !DEF: /omp_docollapse/j ObjectEntity INTEGER(4) + !DEF: /omp_docollapse/k ObjectEntity INTEGER(4) + integer i, j, k +!$omp do collapse(2) + !DEF: /omp_docollapse/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + !REF: /omp_docollapse/k + do k=1,10 + print *, "hello" + end do + end do + end do +!$omp end do + + !REF: /omp_docollapse/i + do i=1,10 +!$omp do collapse(2) + !DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + !DEF: /omp_docollapse/Block1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=1,10 + print *, "hello" + end do + end do +!$omp end do + end do +end program omp_docollapse diff --git a/flang/test/Semantics/omp-do-collapse.f90 b/flang/test/Semantics/omp-do-collapse.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-collapse.f90 @@ -0,0 +1,26 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Collapse Clause +program omp_doCollapse + integer:: i,j + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do collapse(3) + do i = 1,10 + do j = 1, 10 + print *, "hello" + end do + end do + !$omp end do + + do i = 1,10 + do j = 1, 10 + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do collapse(2) + do k = 1, 10 + print *, "hello" + end do + !$omp end do + end do + end do +end program omp_doCollapse + diff --git a/flang/test/Semantics/omp-do-ordered-positivecases.f90 b/flang/test/Semantics/omp-do-ordered-positivecases.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-ordered-positivecases.f90 @@ -0,0 +1,63 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Ordered Clause positive cases. + +!DEF: /omp_doordered MainProgram +program omp_doordered + !DEF: /omp_doordered/i ObjectEntity INTEGER(4) + !DEF: /omp_doordered/j ObjectEntity INTEGER(4) + integer i, j +!$omp do ordered(2) + !DEF: /omp_doordered/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_doordered/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + print *, "hello" + end do + end do +!$omp end do + !REF: /omp_doordered/i + do i=1,10 + !REF: /omp_doordered/j + do j=1,10 +!$omp do ordered(1) + !DEF: /omp_doordered/Block2/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=1,10 + print *, "hello" + end do +!$omp end do + end do + end do +!$omp do ordered(1) + !DEF: /omp_doordered/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 +!$omp ordered + !REF: /omp_doordered/j + do j=1,10 + print *, "hello" + end do +!$omp end ordered + end do +!$omp end do +!$omp do collapse(1) ordered(2) + !DEF: /omp_doordered/Block4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_doordered/Block4/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + print *, "hello" + end do + end do +!$omp end do +!$omp parallel num_threads(4) +!$omp do ordered(1) collapse(1) + !DEF: /omp_doordered/Block5/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 +!$omp ordered + !DEF: /omp_doordered/Block5/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + print *, "hello" + end do +!$omp end ordered + end do +!$omp end parallel +end program omp_doordered diff --git a/flang/test/Semantics/omp-do-ordered.f90 b/flang/test/Semantics/omp-do-ordered.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-ordered.f90 @@ -0,0 +1,58 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Ordered Clause + +program omp_doOrdered + integer:: i,j + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(3) + do i = 1,10 + do j = 1, 10 + print *, "hello" + end do + end do + !$omp end do + + do i = 1,10 + do j = 1, 10 + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(2) + do k = 1, 10 + print *, "hello" + end do + !$omp end do + end do + end do + + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(2) + do i = 1,10 + !$omp ordered + do j = 1, 10 + print *, "hello" + end do + !$omp end ordered + end do + !$omp end do + + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do collapse(1) ordered(3) + do i = 1,10 + do j = 1, 10 + print *, "hello" + end do + end do + !$omp end do + + !$omp parallel num_threads(4) + !ERROR: The value of the parameter in the collapse or ordered clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(2) collapse(1) + do i = 1,10 + !$omp ordered + do j = 1, 10 + print *, "hello" + end do + !$omp end ordered + end do + !$omp end parallel +end program omp_doOrdered