Index: flang/lib/Semantics/check-directive-structure.h =================================================================== --- flang/lib/Semantics/check-directive-structure.h +++ flang/lib/Semantics/check-directive-structure.h @@ -58,6 +58,13 @@ std::list actualClauses; }; + // OpenMP 4.5 : 2.15.3.2 and 2.15.3.3 + const parser::StructureComponent *CheckAssociatedVariant( + const parser::Name &name, const parser::DataRef &dataRef); + + // OpenMP 4.5 : 2.15.3.2 and 2.15.3.3 + void CheckObjectListStructure(const parser::OmpObjectList &x); + // back() is the top of the stack DirectiveContext &GetContext() { CHECK(!dirContext_.empty()); @@ -186,6 +193,65 @@ std::string ClauseSetToString(const common::EnumSet set); }; +// OpenMP 4.5 : 2.15.3.2 and 2.15.3.3 +template +void DirectiveStructureChecker:: + CheckObjectListStructure(const parser::OmpObjectList &objList) { + + for (const auto &ompObject : objList.v) { + std::visit( + common::visitors{ + [&](const parser::Designator &designator) { + if (const auto *dataRef{ + std::get_if(&designator.u)}) { + + const parser::Name *name{ + std::get_if(&dataRef->u)}; + + if (const parser::StructureComponent * + ssc{CheckAssociatedVariant(*name, *dataRef)}) { + + context_.Say(GetContext().clauseSource, + "A variable that is part of another variable (as an " + "array or structure element)" + " cannot appear in a private or shared clause."_err_en_US); + } + } + }, + [&](const parser::Name &name) {}, + + }, + + ompObject.u); + } +} + +// OpenMP 4.5 : 2.15.3.2 and 2.15.3.3 +template +const parser::StructureComponent * +DirectiveStructureChecker::CheckAssociatedVariant( + const parser::Name &name, const parser::DataRef &dataRef) { + + return std::visit( + common::visitors{ + + [&](const parser::Name &name) -> const parser::StructureComponent * { + return nullptr; + }, + + [&](const common::Indirection &sc) + -> const parser::StructureComponent * { return &sc.value(); }, + + [&](const common::Indirection &ae) + -> const parser::StructureComponent * { return nullptr; }, + + [&](const common::Indirection &ci) + -> const parser::StructureComponent * { return nullptr; }, + + }, + dataRef.u); +} + // Check that only clauses included in the given set are present after the given // clause. template Index: flang/lib/Semantics/check-omp-structure.cpp =================================================================== --- flang/lib/Semantics/check-omp-structure.cpp +++ flang/lib/Semantics/check-omp-structure.cpp @@ -407,15 +407,21 @@ CheckAllowed(llvm::omp::Clause::OMPC_priority); RequiresPositiveParameter(llvm::omp::Clause::OMPC_priority, x.v); } -void OmpStructureChecker::Enter(const parser::OmpClause::Private &) { +void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) { CheckAllowed(llvm::omp::Clause::OMPC_private); + + // OpenMP 4.5 : 2.15.3.3 + CheckObjectListStructure(x.v); } void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) { CheckAllowed(llvm::omp::Clause::OMPC_safelen); RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_safelen, x.v); } -void OmpStructureChecker::Enter(const parser::OmpClause::Shared &) { +void OmpStructureChecker::Enter(const parser::OmpClause::Shared &x) { CheckAllowed(llvm::omp::Clause::OMPC_shared); + + // OpenMP 4.5 : 2.15.3.2 + CheckObjectListStructure(x.v); } void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) { CheckAllowed(llvm::omp::Clause::OMPC_simdlen); Index: flang/test/Semantics/omp-parallel-private.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-parallel-private.f90 @@ -0,0 +1,27 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.3 parallel private Clause +program omp_parallel_private + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + + + do i = 1, 10 + a(i) = i + b(i) = i * i + end do + +!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a private or shared clause. + !$omp parallel private(my_var%array) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k + end do + !$omp end parallel + +end program omp_parallel_private Index: flang/test/Semantics/omp-parallel-shared.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-parallel-shared.f90 @@ -0,0 +1,24 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.15.3.2 parallel shared Clause +program omp_parallel_shared + integer :: i, j, a(10), b(10), c(10) + integer :: k = 10 + type my_type + integer :: array(10) + end type my_type + + type(my_type) :: my_var + do i = 1, 10 + a(i) = i + b(i) = i * i + end do +!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a private or shared clause. + !$omp parallel shared(my_var%array) + do i = 1, 10 + c(i) = a(i) + b(i) + k + my_var%array(i) = k + end do + !$omp end parallel + +end program omp_parallel_shared