[flang-commits] [flang] 2685212 - [flang][OpenMP] Add semantic check for threadprivate directive

via flang-commits flang-commits at lists.llvm.org
Tue Sep 14 09:26:03 PDT 2021


Author: PeixinQiao
Date: 2021-09-15T00:22:03+08:00
New Revision: 268521218434bcd3b859e88a0c50369de9d96cf7

URL: https://github.com/llvm/llvm-project/commit/268521218434bcd3b859e88a0c50369de9d96cf7
DIFF: https://github.com/llvm/llvm-project/commit/268521218434bcd3b859e88a0c50369de9d96cf7.diff

LOG: [flang][OpenMP] Add semantic check for threadprivate directive

This patch implements the following check for THREADPRIVATE construct:
```
A variable that is part of another variable (as an array, structure
element or type parameter inquiry) cannot appear in a threadprivate
directive.
```

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D109685

Added: 
    flang/test/Semantics/omp-threadprivate01.f90

Modified: 
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/test/Semantics/omp-allocate03.f90
    flang/test/Semantics/omp-allocate07.f90
    flang/test/Semantics/omp-parallel-private01.f90
    flang/test/Semantics/omp-parallel-private02.f90
    flang/test/Semantics/omp-parallel-private03.f90
    flang/test/Semantics/omp-parallel-private04.f90
    flang/test/Semantics/omp-parallel-shared01.f90
    flang/test/Semantics/omp-parallel-shared02.f90
    flang/test/Semantics/omp-parallel-shared03.f90
    flang/test/Semantics/omp-parallel-shared04.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index a81914f7db278..b765406053ab0 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -816,6 +816,19 @@ void OmpStructureChecker::Leave(const parser::OmpEndSectionsDirective &x) {
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &c) {
+  const auto &dir{std::get<parser::Verbatim>(c.t)};
+  PushContextAndClauseSets(
+      dir.source, llvm::omp::Directive::OMPD_threadprivate);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPThreadprivate &c) {
+  const auto &dir{std::get<parser::Verbatim>(c.t)};
+  const auto &objectList{std::get<parser::OmpObjectList>(c.t)};
+  CheckIsVarPartOfAnotherVar(dir.source, objectList);
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
   PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_declare_simd);
@@ -1518,7 +1531,8 @@ bool OmpStructureChecker::IsDataRefTypeParamInquiry(
 
 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 @@ void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
                       std::get_if<parser::DataRef>(&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<parser::StructureComponent>(
                                ompObject) ||
                     parser::Unwrap<parser::ArrayElement>(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/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index bd0d8100ddd3d..a610a531f8c9b 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -151,6 +151,8 @@ class OmpStructureChecker
   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/test/Semantics/omp-allocate03.f90 b/flang/test/Semantics/omp-allocate03.f90
index 3ff6f7a1a50e8..d1e9686668565 100644
--- a/flang/test/Semantics/omp-allocate03.f90
+++ b/flang/test/Semantics/omp-allocate03.f90
@@ -13,11 +13,10 @@ subroutine allocate()
   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
index 067fc42e5f5ff..80549f9c0187c 100644
--- a/flang/test/Semantics/omp-allocate07.f90
+++ b/flang/test/Semantics/omp-allocate07.f90
@@ -16,19 +16,19 @@ subroutine allocate()
   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
index 6d851af876000..210c72f567e81 100644
--- a/flang/test/Semantics/omp-parallel-private01.f90
+++ b/flang/test/Semantics/omp-parallel-private01.f90
@@ -10,7 +10,7 @@ program omp_parallel_private
 
   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
index aafd4933c829f..3af35f77d14d4 100644
--- a/flang/test/Semantics/omp-parallel-private02.f90
+++ b/flang/test/Semantics/omp-parallel-private02.f90
@@ -10,7 +10,7 @@ program omp_parallel_private
     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
index 2675b44f5358f..5d2778150af19 100644
--- a/flang/test/Semantics/omp-parallel-private03.f90
+++ b/flang/test/Semantics/omp-parallel-private03.f90
@@ -17,7 +17,7 @@ program omp_parallel_private
     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
index 4448f289a46f4..a7516573392a0 100644
--- a/flang/test/Semantics/omp-parallel-private04.f90
+++ b/flang/test/Semantics/omp-parallel-private04.f90
@@ -17,7 +17,7 @@ program omp_parallel_private
     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
index 291467833e82b..9c3fb716697e3 100644
--- a/flang/test/Semantics/omp-parallel-shared01.f90
+++ b/flang/test/Semantics/omp-parallel-shared01.f90
@@ -10,7 +10,7 @@ program omp_parallel_shared
 
   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
index f2eda036398a4..273a6c876dfcb 100644
--- a/flang/test/Semantics/omp-parallel-shared02.f90
+++ b/flang/test/Semantics/omp-parallel-shared02.f90
@@ -10,7 +10,7 @@ program omp_parallel_shared
     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
index 8ae800de84ade..9ff7b24d62c5f 100644
--- a/flang/test/Semantics/omp-parallel-shared03.f90
+++ b/flang/test/Semantics/omp-parallel-shared03.f90
@@ -17,7 +17,7 @@ program omp_parallel_shared
     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
index cd18a9e933c36..1ddb758aa8abb 100644
--- a/flang/test/Semantics/omp-parallel-shared04.f90
+++ b/flang/test/Semantics/omp-parallel-shared04.f90
@@ -17,7 +17,7 @@ program omp_parallel_shared
     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
index 0000000000000..95175f0dff545
--- /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


        


More information about the flang-commits mailing list