diff --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h --- a/flang/lib/Semantics/check-directive-structure.h +++ b/flang/lib/Semantics/check-directive-structure.h @@ -168,8 +168,8 @@ void RequiresConstantPositiveParameter( const C &clause, const parser::ScalarIntConstantExpr &i); - void RequiresPositiveParameter( - const C &clause, const parser::ScalarIntExpr &i); + void RequiresPositiveParameter(const C &clause, + const parser::ScalarIntExpr &i, parser::MessageFixedText msg = {"", 0}); void OptionalConstantPositiveParameter( const C &clause, const std::optional &o); @@ -373,13 +373,18 @@ template void DirectiveStructureChecker::RequiresPositiveParameter(const C &clause, - const parser::ScalarIntExpr &i) { + const parser::ScalarIntExpr &i, parser::MessageFixedText msg) { if (const auto v{GetIntValue(i)}) { if (*v <= 0) { - context_.Say(GetContext().clauseSource, - "The parameter of the %s clause must be " - "a positive integer expression"_err_en_US, - parser::ToUpperCaseLetters(getClauseName(clause).str())); + if (msg.text().empty()) { + context_.Say(GetContext().clauseSource, + "The parameter of the %s clause must be " + "a positive integer expression"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clause).str())); + } else { + context_.Say(GetContext().clauseSource, std::move(msg), + parser::ToUpperCaseLetters(getClauseName(clause).str())); + } } } } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -603,6 +603,12 @@ parser::ToUpperCaseLetters( parser::OmpScheduleClause::EnumToString(kind))); } + if (const auto &chunkExpr{ + std::get>(x.t)}) { + RequiresPositiveParameter(llvm::omp::Clause::OMPC_schedule, *chunkExpr, + "The chunk size of the schedule clause must be" + " a positive integer expression."_err_en_US); + } } if (ScheduleModifierHasType( diff --git a/flang/test/Semantics/omp-do-schedule.f90 b/flang/test/Semantics/omp-do-schedule.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-schedule.f90 @@ -0,0 +1,13 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Schedule Clause +program omp_doSchedule + integer :: i,n + real :: a(100), y(100), z(100) + !ERROR: The chunk size of the schedule clause must be a positive integer expression. + !$omp do schedule(static, -1) + do i=2,n+1 + y(i) = z(i-1) + a(i) + end do + !$omp end do +end program omp_doSchedule diff --git a/flang/test/Semantics/omp-do-schedule02.f90 b/flang/test/Semantics/omp-do-schedule02.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-schedule02.f90 @@ -0,0 +1,15 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Schedule Clause +program omp_doSchedule + integer :: i,n + real :: a(100), y(100), z(100) + integer,parameter :: b = 10 + integer,parameter :: c = 11 + !ERROR: The chunk size of the schedule clause must be a positive integer expression. + !$omp do schedule(static,b-c) + do i=2,n+1 + y(i) = z(i-1) + a(i) + end do + !$omp end do +end program omp_doSchedule diff --git a/flang/test/Semantics/omp-do-schedule03.f90 b/flang/test/Semantics/omp-do-schedule03.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-schedule03.f90 @@ -0,0 +1,28 @@ +! RUN: %S/test_symbols.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Schedule Clause +! Test that does not catch non constant integer expressions like xx - xx. + !DEF: /ompdoschedule MainProgram + program ompdoschedule + !DEF: /ompdoschedule/a ObjectEntity REAL(4) + !DEF: /ompdoschedule/y ObjectEntity REAL(4) + !DEF: /ompdoschedule/z ObjectEntity REAL(4) + real a(100),y(100),z(100) + !DEF: /ompdoschedule/b ObjectEntity INTEGER(4) + !DEF: /ompdoschedule/i ObjectEntity INTEGER(4) + !DEF: /ompdoschedule/n ObjectEntity INTEGER(4) + integer b,i,n + !REF: /ompdoschedule/b + b = 10 +!$omp do schedule(static,b-b) + !DEF: /ompdoschedule/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + !REF: /ompdoschedule/n + do i = 2,n+1 + !REF: /ompdoschedule/y + !REF: /ompdoschedule/Block1/i + !REF: /ompdoschedule/z + !REF: /ompdoschedule/a + y(i) = z(i-1) + a(i) + end do + !$omp end do +end program ompdoschedule diff --git a/flang/test/Semantics/omp-do-schedule04.f90 b/flang/test/Semantics/omp-do-schedule04.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-schedule04.f90 @@ -0,0 +1,32 @@ +! RUN: %S/test_symbols.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Schedule Clause +! Test that does not catch non constant integer expressions like xx - yy. + + !DEF: /omp_doschedule (Subroutine) Subprogram +subroutine omp_doschedule + implicit none + !DEF: /omp_doschedule/a ObjectEntity REAL(4) + !DEF: /omp_doschedule/y ObjectEntity REAL(4) + !DEF: /omp_doschedule/z ObjectEntity REAL(4) + real a(100),y(100),z(100) + !DEF: /omp_doschedule/i ObjectEntity INTEGER(4) + !DEF: /omp_doschedule/j ObjectEntity INTEGER(4) + !DEF: /omp_doschedule/k ObjectEntity INTEGER(4) + integer i,j,k + + !REF: /omp_doschedule/j + j = 11 + !REF: /omp_doschedule/k + k = 12 +!$omp do schedule(static,j-k) + !DEF: /omp_doschedule/Block1/i (OmpPrivate,OmpPreDetermined) HostAssoc INTEGER(4) + do i = 1,10 + !REF: /omp_doschedule/y + !REF: /omp_doschedule/Block1/i + !REF: /omp_doschedule/z + !REF: /omp_doschedule/a + y(i) = z(i-1)+a(i) + end do + !$omp end do +end subroutine omp_doschedule