[flang-commits] [flang] [Flang][OpenMP] Data-sharing restrictions on assumed-size arrays (PR #189324)

Phoebe Linck via flang-commits flang-commits at lists.llvm.org
Sun Mar 29 23:38:52 PDT 2026


https://github.com/phi-bee created https://github.com/llvm/llvm-project/pull/189324

Per `OpenMP 5.0 2.19.1 Data-Sharing Attribute Rules`, assumed-size arrays are predetermined shared and may not appear in a data-sharing clause besides `shared`.

Patch adds a semantics check for assumed-size arrays appearing in clauses where they aren't allowed.

>From 45fd72690ba8e7bb8680cf569bfdadf9170c43bc Mon Sep 17 00:00:00 2001
From: Phoebe Linck <phoebe.linck at hpe.com>
Date: Tue, 24 Mar 2026 13:32:15 -0500
Subject: [PATCH] [Flang][OpenMP] Data-sharing restrictions on assumed-size
 arrays

---
 flang/lib/Semantics/check-omp-loop.cpp        |  1 +
 flang/lib/Semantics/check-omp-structure.cpp   | 15 ++++++
 flang/lib/Semantics/check-omp-structure.h     |  1 +
 .../OpenMP/assumed-size-array-dsa.f90         | 48 +++++++++++++++++++
 .../Semantics/OpenMP/cray-pointer-usage.f90   |  3 ++
 5 files changed, 68 insertions(+)
 create mode 100644 flang/test/Semantics/OpenMP/assumed-size-array-dsa.f90

diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index e35e83e5b191b..ca0529231fa6a 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -657,6 +657,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
   auto &objects{std::get<parser::OmpObjectList>(x.v.t)};
   CheckCrayPointee(objects, "LINEAR", false);
   GetSymbolsInObjectList(objects, symbols);
+  CheckAssumedSizeArray(symbols, llvm::omp::Clause::OMPC_linear);
 
   auto CheckIntegerNoRef{[&](const Symbol *symbol, parser::CharBlock source) {
     if (!symbol->GetType()->IsNumeric(TypeCategory::Integer)) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 0c182e35de068..52b9fcc4cd41d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -3982,6 +3982,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) {
   CheckVarIsNotPartOfAnotherVar(GetContext().clauseSource, x.v, "PRIVATE");
   CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_private);
   CheckCrayPointee(x.v, "PRIVATE");
+  CheckAssumedSizeArray(symbols, llvm::omp::Clause::OMPC_private);
 }
 
 void OmpStructureChecker::Enter(const parser::OmpClause::Nowait &x) {
@@ -4060,6 +4061,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) {
   GetSymbolsInObjectList(x.v, currSymbols);
   CheckCopyingPolymorphicAllocatable(
       currSymbols, llvm::omp::Clause::OMPC_firstprivate);
+  CheckAssumedSizeArray(currSymbols, llvm::omp::Clause::OMPC_firstprivate);
 
   DirectivesClauseTriple dirClauseTriple;
   // Check firstprivate variables in worksharing constructs
@@ -4731,6 +4733,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
   CheckIntentInPointer(currSymbols, llvm::omp::Clause::OMPC_lastprivate);
   CheckCopyingPolymorphicAllocatable(
       currSymbols, llvm::omp::Clause::OMPC_lastprivate);
+  CheckAssumedSizeArray(currSymbols, llvm::omp::Clause::OMPC_lastprivate);
 
   // Check lastprivate variables in worksharing constructs
   dirClauseTriple.emplace(llvm::omp::Directive::OMPD_do,
@@ -5203,6 +5206,18 @@ void OmpStructureChecker::CheckIntentInPointer(
   }
 }
 
+void OmpStructureChecker::CheckAssumedSizeArray(
+    SymbolSourceMap &symbols, llvm::omp::Clause clauseId) {
+  unsigned version{context_.langOptions().OpenMPVersion};
+  for (auto &[symbol, source] : symbols) {
+    if (IsAssumedSizeArray(*symbol)) {
+      context_.Say(source,
+          "Assumed-size array '%s' not allowed in a %s clause"_err_en_US,
+          symbol->name(), parser::omp::GetUpperName(clauseId, version));
+    }
+  }
+}
+
 void OmpStructureChecker::CheckProcedurePointer(
     SymbolSourceMap &symbols, llvm::omp::Clause clause) {
   unsigned version{context_.langOptions().OpenMPVersion};
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index dc84c9d9ae9d8..5170c27c58d89 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -259,6 +259,7 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
   void CheckSymbolNames(
       const parser::CharBlock &source, const parser::OmpObjectList &objList);
   void CheckIntentInPointer(SymbolSourceMap &, const llvm::omp::Clause);
+  void CheckAssumedSizeArray(SymbolSourceMap &, const llvm::omp::Clause);
   void CheckProcedurePointer(SymbolSourceMap &, const llvm::omp::Clause);
   void CheckCrayPointee(const parser::OmpObjectList &objectList,
       llvm::StringRef clause, bool suggestToUseCrayPointer = true);
diff --git a/flang/test/Semantics/OpenMP/assumed-size-array-dsa.f90 b/flang/test/Semantics/OpenMP/assumed-size-array-dsa.f90
new file mode 100644
index 0000000000000..8b5f1feeb8279
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/assumed-size-array-dsa.f90
@@ -0,0 +1,48 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! Assumed-size arrays are predetermined shared and may only appear in a SHARED clause
+subroutine test_assumed_size_array_dsa( arr, N )
+  implicit none
+  integer :: arr(*)
+  integer :: i, N
+
+  !$omp parallel
+
+  !$omp task shared(arr)
+  do i = 1, N
+    print *, arr(i)
+  end do
+  !$omp end task
+
+  ! ERROR: Assumed-size array 'arr' not allowed in a PRIVATE clause
+  !$omp task private(arr)
+  do i = 1, N
+    print *, arr(i)
+  end do
+  !$omp end task
+
+  ! ERROR: Assumed-size array 'arr' not allowed in a FIRSTPRIVATE clause
+  !$omp task firstprivate(arr)
+  do i = 1, N
+    print *, arr(i)
+  end do
+  !$omp end task
+
+  ! ERROR: Assumed-size array 'arr' not allowed in a LASTPRIVATE clause
+  !$omp do lastprivate(arr)
+  do i = 1, N
+    print *, arr(i)
+  end do
+  !$omp end do
+
+  ! ERROR: Assumed-size array 'arr' not allowed in a LINEAR clause
+  ! ERROR: List item 'arr' in LINEAR clause must be a scalar variable
+  !$omp do linear(arr)
+  do i = 1, N
+    print *, arr(i)
+  end do
+  !$omp end do
+
+  !$omp end parallel
+
+end subroutine
diff --git a/flang/test/Semantics/OpenMP/cray-pointer-usage.f90 b/flang/test/Semantics/OpenMP/cray-pointer-usage.f90
index 3f13338a19f7f..07062b72b631d 100644
--- a/flang/test/Semantics/OpenMP/cray-pointer-usage.f90
+++ b/flang/test/Semantics/OpenMP/cray-pointer-usage.f90
@@ -8,6 +8,7 @@ subroutine test_cray_pointer_usage
   ! ERROR: List item 'var' in LINEAR clause must be a scalar variable
   ! ERROR: The list item 'var' specified without the REF 'linear-modifier' must be of INTEGER type
   ! ERROR: The list item `var` must be a dummy argument
+  ! ERROR: Assumed-size array 'var' not allowed in a LINEAR clause
   !$omp declare simd linear(var)
 
   pointee = 42.0
@@ -19,6 +20,7 @@ subroutine test_cray_pointer_usage
   !$omp end parallel
 
   ! ERROR: Cray Pointee 'var' may not appear in PRIVATE clause, use Cray Pointer 'ivar' instead
+  ! ERROR: Assumed-size array 'var' not allowed in a PRIVATE clause
   !$omp parallel num_threads(2) default(none) private(var)
     print *, var(1)
   !$omp end parallel
@@ -29,6 +31,7 @@ subroutine test_cray_pointer_usage
   !$omp end parallel
 
   ! ERROR: Cray Pointee 'var' may not appear in LASTPRIVATE clause, use Cray Pointer 'ivar' instead
+  ! ERROR: Assumed-size array 'var' not allowed in a LASTPRIVATE clause
   !$omp do lastprivate(var)
     do i = 1, 10
       print *, var(1)



More information about the flang-commits mailing list