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 @@ -151,6 +151,8 @@ void Leave(const parser::OpenMPDeclareTargetConstruct &); void Enter(const parser::OpenMPExecutableAllocate &); void Leave(const parser::OpenMPExecutableAllocate &); + void Enter(const parser::OpenMPThreadprivate &); + void Leave(const parser::OpenMPThreadprivate &); void Enter(const parser::OpenMPSimpleStandaloneConstruct &); void Leave(const parser::OpenMPSimpleStandaloneConstruct &); 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 @@ -816,6 +816,19 @@ } } +void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &c) { + const auto &dir{std::get(c.t)}; + PushContextAndClauseSets( + dir.source, llvm::omp::Directive::OMPD_threadprivate); +} + +void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &c) { + const auto &dir{std::get(c.t)}; + const auto &objectList{std::get(c.t)}; + CheckIsVarPartOfAnotherVar(dir.source, objectList); + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) { const auto &dir{std::get(x.t)}; PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_declare_simd); @@ -1518,7 +1531,8 @@ void OmpStructureChecker::CheckIsVarPartOfAnotherVar( const parser::CharBlock &source, const parser::OmpObjectList &objList) { - + OmpDirectiveSet nonPartialVarSet{llvm::omp::Directive::OMPD_allocate, + llvm::omp::Directive::OMPD_threadprivate}; for (const auto &ompObject : objList.v) { std::visit( common::visitors{ @@ -1527,14 +1541,24 @@ std::get_if(&designator.u)}) { if (IsDataRefTypeParamInquiry(dataRef)) { context_.Say(source, - "A type parameter inquiry cannot appear in an ALLOCATE directive"_err_en_US); + "A type parameter inquiry cannot appear on the %s " + "directive"_err_en_US, + ContextDirectiveAsFortran()); } else if (parser::Unwrap( ompObject) || parser::Unwrap(ompObject)) { - context_.Say(source, - "A variable that is part of another variable (as an " - "array or structure element)" - " cannot appear in a PRIVATE or SHARED clause or on the ALLOCATE directive."_err_en_US); + if (nonPartialVarSet.test(GetContext().directive)) { + context_.Say(source, + "A variable that is part of another variable (as an " + "array or structure element) cannot appear on the %s " + "directive"_err_en_US, + ContextDirectiveAsFortran()); + } else { + context_.Say(source, + "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); + } } } }, diff --git a/flang/test/Semantics/omp-allocate03.f90 b/flang/test/Semantics/omp-allocate03.f90 --- a/flang/test/Semantics/omp-allocate03.f90 +++ b/flang/test/Semantics/omp-allocate03.f90 @@ -13,11 +13,10 @@ real, dimension (:,:), allocatable :: darray integer :: a, b - !!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in an ALLOCATE directive - !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE or SHARED clause or on the ALLOCATE directive. + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATE directive !$omp allocate(my_var%array) - !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE or SHARED clause or on the ALLOCATE directive. + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATE directive !$omp allocate(darray, my_var%array) allocator(omp_default_mem_alloc) allocate ( darray(a, b) ) diff --git a/flang/test/Semantics/omp-allocate07.f90 b/flang/test/Semantics/omp-allocate07.f90 --- a/flang/test/Semantics/omp-allocate07.f90 +++ b/flang/test/Semantics/omp-allocate07.f90 @@ -16,19 +16,19 @@ CHARACTER(LEN=32) :: w INTEGER, DIMENSION(:), ALLOCATABLE :: y - !ERROR: A type parameter inquiry cannot appear in an ALLOCATE directive + !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive !$omp allocate(x%KIND) - !ERROR: A type parameter inquiry cannot appear in an ALLOCATE directive + !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive !$omp allocate(w%LEN) - !ERROR: A type parameter inquiry cannot appear in an ALLOCATE directive + !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive !$omp allocate(y%KIND) - !ERROR: A type parameter inquiry cannot appear in an ALLOCATE directive + !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive !$omp allocate(my_var%kind_param) - !ERROR: A type parameter inquiry cannot appear in an ALLOCATE directive + !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive !$omp allocate(my_var%len_param) end subroutine allocate diff --git a/flang/test/Semantics/omp-parallel-private01.f90 b/flang/test/Semantics/omp-parallel-private01.f90 --- a/flang/test/Semantics/omp-parallel-private01.f90 +++ b/flang/test/Semantics/omp-parallel-private01.f90 @@ -10,7 +10,7 @@ type(my_type) :: my_var - !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE or SHARED clause or on the ALLOCATE directive. + !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 diff --git a/flang/test/Semantics/omp-parallel-private02.f90 b/flang/test/Semantics/omp-parallel-private02.f90 --- a/flang/test/Semantics/omp-parallel-private02.f90 +++ b/flang/test/Semantics/omp-parallel-private02.f90 @@ -10,7 +10,7 @@ array(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 or on the ALLOCATE directive. + !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(array(i)) do i = 1, 10 c(i) = a(i) + b(i) + k diff --git a/flang/test/Semantics/omp-parallel-private03.f90 b/flang/test/Semantics/omp-parallel-private03.f90 --- a/flang/test/Semantics/omp-parallel-private03.f90 +++ b/flang/test/Semantics/omp-parallel-private03.f90 @@ -17,7 +17,7 @@ arr(i) = 0.0 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 or on the ALLOCATE directive. + !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(arr(i),intx) do i = 1, 10 c(i) = a(i) + b(i) + k diff --git a/flang/test/Semantics/omp-parallel-private04.f90 b/flang/test/Semantics/omp-parallel-private04.f90 --- a/flang/test/Semantics/omp-parallel-private04.f90 +++ b/flang/test/Semantics/omp-parallel-private04.f90 @@ -17,7 +17,7 @@ arr(i) = 0.0 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 or on the ALLOCATE directive. + !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(arr,intx,my_var%array(1)) do i = 1, 10 c(i) = a(i) + b(i) + k diff --git a/flang/test/Semantics/omp-parallel-shared01.f90 b/flang/test/Semantics/omp-parallel-shared01.f90 --- a/flang/test/Semantics/omp-parallel-shared01.f90 +++ b/flang/test/Semantics/omp-parallel-shared01.f90 @@ -10,7 +10,7 @@ type(my_type) :: my_var - !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE or SHARED clause or on the ALLOCATE directive. + !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 diff --git a/flang/test/Semantics/omp-parallel-shared02.f90 b/flang/test/Semantics/omp-parallel-shared02.f90 --- a/flang/test/Semantics/omp-parallel-shared02.f90 +++ b/flang/test/Semantics/omp-parallel-shared02.f90 @@ -10,7 +10,7 @@ array(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 or on the ALLOCATE directive. + !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(array(i)) do i = 1, 10 c(i) = a(i) + b(i) + k diff --git a/flang/test/Semantics/omp-parallel-shared03.f90 b/flang/test/Semantics/omp-parallel-shared03.f90 --- a/flang/test/Semantics/omp-parallel-shared03.f90 +++ b/flang/test/Semantics/omp-parallel-shared03.f90 @@ -17,7 +17,7 @@ arr(i) = 0.0 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 or on the ALLOCATE directive. + !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(arr(i),intx) do i = 1, 10 c(i) = a(i) + b(i) + k diff --git a/flang/test/Semantics/omp-parallel-shared04.f90 b/flang/test/Semantics/omp-parallel-shared04.f90 --- a/flang/test/Semantics/omp-parallel-shared04.f90 +++ b/flang/test/Semantics/omp-parallel-shared04.f90 @@ -17,7 +17,7 @@ arr(i) = 0.0 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 or on the ALLOCATE directive. + !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(arr,intx,my_var%array(1)) do i = 1, 10 c(i) = a(i) + b(i) + k diff --git a/flang/test/Semantics/omp-threadprivate01.f90 b/flang/test/Semantics/omp-threadprivate01.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-threadprivate01.f90 @@ -0,0 +1,51 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 -fopenmp +! OpenMP Version 5.1 +! Check OpenMP construct validity for the following directives: +! 2.21.2 Threadprivate Directive + +module thread_private01 + use omp_lib + type my_type(kind_param, len_param) + integer, KIND :: kind_param + integer, LEN :: len_param + integer :: t_i + integer :: t_arr(10) + end type my_type + + type(my_type(2, 4)) :: my_var + integer :: arr(10) + integer(kind=4) :: x + character(len=32) :: w + integer, dimension(:), allocatable :: y + + !$omp threadprivate(my_var) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%t_i) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%t_arr) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%kind_param) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(my_var%len_param) + + !$omp threadprivate(arr) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(arr(1)) + + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive + !$omp threadprivate(arr(1:2)) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(x%KIND) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(w%LEN) + + !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive + !$omp threadprivate(y%KIND) +end