diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -175,6 +175,14 @@ llvm::StringRef getClauseName(llvm::omp::Clause clause) override; llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override; + + std::optional chunkSize{0}; + std::optional GetChunkSize() { return chunkSize; } + void SetChunkSize(const parser::ScalarIntExpr &chunkExpr) { + if (std::optional v{GetIntValue(chunkExpr)}) { + chunkSize.emplace(*v); + } + } }; } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_ 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 @@ -405,6 +405,7 @@ // Restrictions specific to each clause are implemented apart from the // generalized restrictions. + void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) { CheckAllowed(llvm::omp::Clause::OMPC_ordered); // the parameter of ordered clause is optional @@ -578,10 +579,24 @@ parser::ToUpperCaseLetters( parser::OmpScheduleClause::EnumToString(kind))); } + if (const auto &chunkExpr{ std::get>(x.t)}) { RequiresPositiveParameter( llvm::omp::Clause::OMPC_schedule, *chunkExpr, "chunk size"); + + if (kind == parser::OmpScheduleClause::ScheduleType::Static) { + if (const auto cv{GetIntValue(chunkExpr)}) { + const auto cs{GetChunkSize()}; + if (!*cs) { + SetChunkSize(*chunkExpr); + } else if (cs != cv) { + context_.Say(GetContext().clauseSource, + "The value of chunk size in SCHEDULE clause must" + " be the same for all threads."_err_en_US); + } + } + } } } diff --git a/flang/test/Semantics/omp-schedule-teams.f90 b/flang/test/Semantics/omp-schedule-teams.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-schedule-teams.f90 @@ -0,0 +1,30 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Teams - Schedule Clause + +program omp_doschedule + integer,parameter :: N = 14 + integer :: i + integer :: sumx + real :: B(N), C(N) + + !$omp target + !$omp teams + !$omp parallel + !$omp do schedule(static, 4) + do i = 1,N + sumx = sumx + B(i) * C(i) + end do + + !ERROR: The value of chunk size in SCHEDULE clause must be the same for all threads. + !$omp do schedule(static, 8) + do i = 1,N + sumx = sumx + B(i) * C(i) + end do + + !$omp end do + !$omp end parallel + !$omp end teams + !$omp end target + +end program omp_doschedule