[flang-commits] [flang] [flang][openmp] Add semantic checks in THREADPRIVATE/DECLARE TARGET (PR #209084)

via flang-commits flang-commits at lists.llvm.org
Sun Jul 12 22:18:56 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Thirumalai Shaktivel (Thirumalai-Shaktivel)

<details>
<summary>Changes</summary>

The problem is that the automatic object was used as the threadprivate argument.

Solution:
>From the documentation (J3/24-007):
> C814 An automatic data object shall not have the SAVE attribute.
> C862 The SAVE attribute shall not be specified for a dummy argument,
>      a function result, an automatic data object, or an object
>      that is in a common block.

The bare SAVE statement makes any valid local variables tagged with the SAVE attribute. As the restriction mentioned above, the automatic object cannot have a SAVE attribute and shall not be used as the THREADPRIVATE argument. This patch adds semantic checks for dummy arguments, function results, and automatic data objects in both THREADPRIVATE and DECLARE TARGET directives.

---
Full diff: https://github.com/llvm/llvm-project/pull/209084.diff


3 Files Affected:

- (modified) flang/lib/Semantics/check-omp-structure.cpp (+12) 
- (modified) flang/test/Semantics/OpenMP/declare-target02.f90 (+32) 
- (modified) flang/test/Semantics/OpenMP/threadprivate02.f90 (+66) 


``````````diff
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 68d7a166be0fb..137b6b35f15d5 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1786,6 +1786,18 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
     context_.Say(name->source,
         "A variable in a %s directive cannot appear in an EQUIVALENCE statement"_err_en_US,
         ContextDirectiveAsFortran());
+  } else if (IsDummy(*name->symbol)) {
+    context_.Say(name->source,
+        "A dummy argument cannot appear in %s, because it cannot be given the SAVE attribute"_err_en_US,
+        ContextDirectiveAsFortran());
+  } else if (IsAutomatic(*name->symbol)) {
+    context_.Say(name->source,
+        "An automatic data object cannot appear in %s, because it cannot be given the SAVE attribute"_err_en_US,
+        ContextDirectiveAsFortran());
+  } else if (IsFunctionResult(*name->symbol)) {
+    context_.Say(name->source,
+        "A function result object cannot appear in %s, because it cannot be given the SAVE attribute"_err_en_US,
+        ContextDirectiveAsFortran());
   } else if (name->symbol->test(Symbol::Flag::OmpThreadprivate) &&
       directive == llvm::omp::Directive::OMPD_declare_target) {
     context_.Say(name->source,
diff --git a/flang/test/Semantics/OpenMP/declare-target02.f90 b/flang/test/Semantics/OpenMP/declare-target02.f90
index 1dddb62231d82..098b8f8b178ff 100644
--- a/flang/test/Semantics/OpenMP/declare-target02.f90
+++ b/flang/test/Semantics/OpenMP/declare-target02.f90
@@ -204,3 +204,35 @@ subroutine func5()
   !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
   !$omp declare target link (a5_link)
 end
+
+subroutine func6
+    common /foo/ l
+    integer l
+    integer k(l)
+    save
+    !ERROR: An automatic data object cannot appear in DECLARE TARGET, because it cannot be given the SAVE attribute
+    !$omp declare target(k)
+end subroutine
+
+subroutine func7(a)
+    integer :: a(:)
+    save
+    !ERROR: A dummy argument cannot appear in DECLARE TARGET, because it cannot be given the SAVE attribute
+    !$omp declare target(a)
+end subroutine
+
+integer function func8()
+    save
+    !$omp declare target(func8)
+end function
+
+integer function func9()
+    integer :: x
+    common /blk/ x
+    save
+    !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+    !$omp declare target(x)
+
+    ! PASS
+    !$omp declare target(/blk/)
+end function
diff --git a/flang/test/Semantics/OpenMP/threadprivate02.f90 b/flang/test/Semantics/OpenMP/threadprivate02.f90
index 6ac024780aa79..b49af65843d2c 100644
--- a/flang/test/Semantics/OpenMP/threadprivate02.f90
+++ b/flang/test/Semantics/OpenMP/threadprivate02.f90
@@ -86,3 +86,69 @@ subroutine func5()
   !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
   !$omp threadprivate(a5)
 end
+
+subroutine func6
+    common /foo/ l
+    integer l
+    integer k(l)
+    save
+    !ERROR: An automatic data object cannot appear in THREADPRIVATE, because it cannot be given the SAVE attribute
+    !$omp threadprivate(k)
+end subroutine func6
+
+subroutine func7()
+    integer :: x
+    common /blk/ x
+    save
+    !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
+    !$omp threadprivate(x)
+
+    ! PASS
+    !$omp threadprivate(/blk/)
+end subroutine
+
+module mod_func8
+    integer, save :: x
+contains
+    subroutine func8()
+        !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+        !$omp threadprivate(x)
+    end subroutine
+end module
+
+subroutine func9()
+    use mod_func8
+    !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+    !$omp threadprivate(x)
+end subroutine
+
+subroutine func10()
+    !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+    !$omp threadprivate(x)
+    x = 1
+end subroutine
+
+subroutine func11
+    type :: t
+      integer :: a = 12
+    end type t
+    type(t) :: x
+    integer :: i, j
+
+    save :: x, j
+    !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+    !$omp threadprivate(x, i, j)
+end subroutine
+
+subroutine func12(a)
+    integer :: a(:)
+    save
+    !ERROR: A dummy argument cannot appear in THREADPRIVATE, because it cannot be given the SAVE attribute
+    !$omp threadprivate(a)
+end subroutine
+
+integer function func13()
+    save
+    !ERROR: A function result object cannot appear in THREADPRIVATE, because it cannot be given the SAVE attribute
+    !$omp threadprivate(func13)
+end function

``````````

</details>


https://github.com/llvm/llvm-project/pull/209084


More information about the flang-commits mailing list