[flang-commits] [flang] [flang][openacc] Fix DEFAULT(NONE) errors for array sections (PR #204248)

Andre Kuhlenschmidt via flang-commits flang-commits at lists.llvm.org
Thu Jun 25 17:46:50 PDT 2026


https://github.com/akuhlens updated https://github.com/llvm/llvm-project/pull/204248

>From 630347e6133c16add6064dd9dc019b4ba70ca534 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Mon, 15 Jun 2026 15:08:00 -0700
Subject: [PATCH 1/3] [flang][openacc] Fix spurious DEFAULT(NONE) errors for
 array sections in data clauses

ResolveAccObject skipped DSA registration when GetDesignatorNameIfDataRef
returned nullptr (i.e. for subscripted designators like copyin(a(1:n))).
The DEFAULT(NONE) post-visitor then found the base variable unregistered
and emitted a false error even though it was explicitly listed in a data
clause.

Unify the path using GetFirstName, which extracts the base symbol from
both bare data references and array sections.  Also extend
CheckMultipleAppearances to array-section entries under data-sharing
clauses, which the old else-branch omitted.
---
 flang/lib/Semantics/resolve-directives.cpp    |  31 ++--
 .../OpenACC/acc-default-none-arrays.f90       | 133 ++++++++++++++++++
 2 files changed, 153 insertions(+), 11 deletions(-)
 create mode 100644 flang/test/Semantics/OpenACC/acc-default-none-arrays.f90

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index f3865cfb877dc..d7c466e2f2d13 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1905,24 +1905,33 @@ void AccAttributeVisitor::ResolveAccObject(
   common::visit(
       common::visitors{
           [&](const parser::Designator &designator) {
-            if (const auto *name{
-                    parser::GetDesignatorNameIfDataRef(designator)}) {
-              if (auto *symbol{ResolveAcc(*name, accFlag, currScope())}) {
-                AddToContextObjectWithDSA(*symbol, accFlag);
-                if (dataSharingAttributeFlags.test(accFlag)) {
-                  CheckMultipleAppearances(*name, *symbol, accFlag, &accObject);
-                }
-              }
-            } else {
-              // Array sections to be changed to substrings as needed
+            const bool isDataRef{
+                parser::GetDesignatorNameIfDataRef(designator) != nullptr};
+            if (!isDataRef) {
+              // Subscripted designator: evaluate subscripts and detect
+              // the substring case that is disallowed in OpenACC clauses.
               if (AnalyzeExpr(context_, designator)) {
                 if (std::holds_alternative<parser::Substring>(designator.u)) {
                   context_.Say(designator.source,
                       "Substrings are not allowed on OpenACC "
                       "directives or clauses"_err_en_US);
+                  return;
                 }
               }
-              // other checks, more TBD
+            }
+            // GetFirstName extracts the base symbol from both bare data
+            // references and array sections, unifying DSA registration so
+            // that DEFAULT(NONE) checking does not spuriously flag variables
+            // that are explicitly listed in a data clause as array sections.
+            // TODO: Multiple array sections of the same array with different
+            // data sharing attributes is not currently supported.
+            const parser::Name &baseName{parser::GetFirstName(designator)};
+            if (auto *symbol{ResolveAcc(baseName, accFlag, currScope())}) {
+              AddToContextObjectWithDSA(*symbol, accFlag);
+              if (isDataRef && dataSharingAttributeFlags.test(accFlag)) {
+                CheckMultipleAppearances(
+                    baseName, *symbol, accFlag, &accObject);
+              }
             }
           },
           [&](const parser::Name &name) { // common block
diff --git a/flang/test/Semantics/OpenACC/acc-default-none-arrays.f90 b/flang/test/Semantics/OpenACC/acc-default-none-arrays.f90
new file mode 100644
index 0000000000000..913217a4b94f3
--- /dev/null
+++ b/flang/test/Semantics/OpenACC/acc-default-none-arrays.f90
@@ -0,0 +1,133 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc -fno-openacc-default-none-scalars-strict
+
+! Verify that array sections explicitly listed in OpenACC data clauses are
+! correctly registered as having a DSA, so DEFAULT(NONE) does not produce
+! spurious errors (lorado#3307).  Also covers duplicate detection for array
+! sections and the substring-in-clause error.
+
+! 1. Data-mapping clauses with array sections: no DEFAULT(NONE) errors.
+subroutine test_data_mapping_sections(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n*n), b(n), c(n)
+  integer :: i, j
+  real :: temp
+  !$acc kernels default(none) copyin(a(1:n*n), b(1:n)) copy(c(1:n))
+  !$acc loop gang private(temp)
+  do i = 1, n
+    temp = 0.0
+    !$acc loop vector reduction(+:temp)
+    do j = 1, n
+      temp = temp + a((i-1)*n+j) * b(j)
+    enddo
+    c(i) = temp
+  enddo
+  !$acc end kernels
+end subroutine
+
+! 2. Private clause with array section: no DEFAULT(NONE) error.
+subroutine test_private_section(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n)
+  integer :: i
+  !$acc parallel loop default(none) private(a(:))
+  do i = 1, n
+    a(i) = 0.0
+  end do
+  !$acc end parallel loop
+end subroutine
+
+! 3. Parallel with copyin array section and separate parallel body: no error.
+subroutine test_parallel_copyin_section(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: x(n), y(n)
+  integer :: i
+  !$acc parallel loop default(none) copyin(x(1:n)) copyout(y(1:n))
+  do i = 1, n
+    y(i) = x(i) * 2.0
+  end do
+  !$acc end parallel loop
+end subroutine
+
+! 4. Unlisted array still errors under DEFAULT(NONE) (regression check).
+subroutine test_unlisted_array(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n), b(n)
+  integer :: i
+  !$acc parallel default(none) copyin(a(1:n))
+  !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-mapping clause
+  b(1) = a(1)
+  !$acc end parallel
+end subroutine
+
+! 5. Duplicate bare-name under the same data-sharing clause: warn and dedup.
+!    (Array sections like private(a(1:5), a(6:10)) are not deduplicated because
+!    base-name comparison cannot distinguish different sections of the same array.)
+subroutine test_duplicate_private_bare(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n)
+  integer :: i
+  !WARNING: 'a' appears more than once in the same kind of data-sharing clause on an OpenACC directive; duplicate ignored [-Wopenacc-usage]
+  !$acc parallel loop default(none) private(a, a)
+  do i = 1, n
+    a(i) = 0.0
+  end do
+  !$acc end parallel loop
+end subroutine
+
+! 6. Same bare-name variable in two different data-sharing clauses: error.
+subroutine test_cross_kind_bare(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n)
+  integer :: i
+  !ERROR: 'a' appears in more than one data-sharing clause on the same OpenACC directive
+  !$acc parallel loop default(none) private(a) firstprivate(a)
+  do i = 1, n
+    a(i) = 0.0
+  end do
+  !$acc end parallel loop
+end subroutine
+
+! 7. Substring in an OpenACC clause is disallowed.
+subroutine test_substring()
+  implicit none
+  character(len=10) :: str
+  !ERROR: Substrings are not allowed on OpenACC directives or clauses
+  !$acc parallel default(none) copyin(str(1:5))
+  !$acc end parallel
+end subroutine
+
+! 8. Same array section in conflicting private and copy clauses.
+! TODO: cross-kind detection for array sections is not implemented; no error
+!       produced for 'a(1:n)' appearing in both copy and private.
+subroutine test_cross_kind_sections(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n)
+  integer :: i
+  !$acc parallel loop default(none) copy(a(1:n)) private(a(1:n))
+  do i = 1, n
+    a(i) = 0.0
+  end do
+  !$acc end parallel loop
+end subroutine
+
+! 9. Different sections of the same array in conflicting copy and private clauses.
+! TODO: cross-kind detection for array sections is not implemented; no error
+!       produced for 'a' appearing in both copy and private.
+subroutine test_cross_kind_sections2(n)
+  implicit none
+  integer, intent(in) :: n
+  real :: a(n)
+  integer :: i
+  !$acc parallel loop default(none) copy(a(1:n/2)) private(a(n/2+1:n))
+  do i = 1, n
+    a(i) = 0.0
+  end do
+  !$acc end parallel loop
+end subroutine

>From f0dbcbd4b29ecc67ae0a8567a87436238ca938d8 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Wed, 24 Jun 2026 13:08:23 -0700
Subject: [PATCH 2/3] [flang][openacc] Add component reference DSA coverage

---
 flang/lib/Semantics/resolve-directives.cpp    |  51 ++++++-
 .../OpenACC/acc-component-ref-dsa.f90         | 135 ++++++++++++++++++
 2 files changed, 181 insertions(+), 5 deletions(-)
 create mode 100644 flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index d7c466e2f2d13..d861f527bb10b 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -385,7 +385,8 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
   Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
   Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
   void CheckMultipleAppearances(const parser::Name &, const Symbol &,
-      Symbol::Flag, const parser::AccObject *occurrence = nullptr);
+      Symbol::Flag, const parser::AccObject *occurrence = nullptr,
+      bool warnSameKindDuplicate = true);
   void AllowOnlyArrayAndSubArray(const parser::AccObjectList &objectList);
   void DoNotAllowAssumedSizedArray(const parser::AccObjectList &objectList);
   void AllowOnlyVariable(const parser::AccObject &object);
@@ -1900,6 +1901,41 @@ void AccAttributeVisitor::ResolveAccObjectList(
   }
 }
 
+static bool IsBareNameOrComponentRef(const parser::DataRef &dataRef);
+
+static bool IsBareNameOrComponentRef(
+    const parser::StructureComponent &component) {
+  return IsBareNameOrComponentRef(component.Base());
+}
+
+static bool IsBareNameOrComponentRef(const parser::DataRef &dataRef) {
+  return common::visit(
+      common::visitors{
+          [](const parser::Name &) { return true; },
+          [](const common::Indirection<parser::StructureComponent> &component) {
+            return IsBareNameOrComponentRef(component.value());
+          },
+          [](const common::Indirection<parser::ArrayElement> &) {
+            return false;
+          },
+          [](const common::Indirection<parser::CoindexedNamedObject> &) {
+            return false;
+          },
+      },
+      dataRef.u);
+}
+
+static bool IsBareNameOrComponentRef(const parser::Designator &designator) {
+  return common::visit(
+      common::visitors{
+          [](const parser::DataRef &dataRef) {
+            return IsBareNameOrComponentRef(dataRef);
+          },
+          [](const parser::Substring &) { return false; },
+      },
+      designator.u);
+}
+
 void AccAttributeVisitor::ResolveAccObject(
     const parser::AccObject &accObject, Symbol::Flag accFlag) {
   common::visit(
@@ -1928,9 +1964,10 @@ void AccAttributeVisitor::ResolveAccObject(
             const parser::Name &baseName{parser::GetFirstName(designator)};
             if (auto *symbol{ResolveAcc(baseName, accFlag, currScope())}) {
               AddToContextObjectWithDSA(*symbol, accFlag);
-              if (isDataRef && dataSharingAttributeFlags.test(accFlag)) {
+              if (IsBareNameOrComponentRef(designator) &&
+                  dataSharingAttributeFlags.test(accFlag)) {
                 CheckMultipleAppearances(
-                    baseName, *symbol, accFlag, &accObject);
+                    baseName, *symbol, accFlag, &accObject, isDataRef);
               }
             }
           },
@@ -1988,7 +2025,7 @@ Symbol *AccAttributeVisitor::DeclareOrMarkOtherAccessEntity(
 
 void AccAttributeVisitor::CheckMultipleAppearances(const parser::Name &name,
     const Symbol &symbol, Symbol::Flag accFlag,
-    const parser::AccObject *occurrence) {
+    const parser::AccObject *occurrence, bool warnSameKindDuplicate) {
   const auto *target{&symbol};
   if (HasDataSharingAttributeObject(*target)) {
     // A same-kind duplicate (e.g. private(x, x) or private(x) private(x))
@@ -2000,12 +2037,16 @@ void AccAttributeVisitor::CheckMultipleAppearances(const parser::Name &name,
     // with the same Symbol::Flag may still differ in operator, which is a
     // real conflict that dedup would silently hide.
     auto firstFlag{GetContext().FindSymbolWithDSA(*target)};
-    if (occurrence && firstFlag && *firstFlag == accFlag &&
+    if (warnSameKindDuplicate && occurrence && firstFlag &&
+        *firstFlag == accFlag &&
         accFlag != Symbol::Flag::AccReduction) {
       context_.Warn(common::UsageWarning::OpenAccUsage, name.source,
           "'%s' appears more than once in the same kind of data-sharing clause on an OpenACC directive; duplicate ignored"_warn_en_US,
           name.ToString());
       context_.MarkAccObjectDuplicate(occurrence);
+    } else if (firstFlag && *firstFlag == accFlag &&
+        accFlag != Symbol::Flag::AccReduction) {
+      return;
     } else {
       context_.Say(name.source,
           "'%s' appears in more than one data-sharing clause on the same OpenACC directive"_err_en_US,
diff --git a/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90 b/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90
new file mode 100644
index 0000000000000..1c651153339da
--- /dev/null
+++ b/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90
@@ -0,0 +1,135 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc -fno-openacc-default-none-scalars-strict
+
+! Derived-type component references in OpenACC data clauses should register the
+! base object for DEFAULT(NONE) checking and for bare component DSA conflicts.
+
+module component_ref_types
+  implicit none
+  type :: point_t
+    real :: x
+    real :: y
+  end type
+  type :: vec_t
+    real :: arr(10)
+    real :: scale
+  end type
+  type :: nested_t
+    type(point_t) :: pt
+    integer :: tag
+  end type
+end module
+
+subroutine test_component_clauses_are_accepted()
+  use component_ref_types, only: nested_t, point_t, vec_t
+  type(point_t) :: p
+  type(vec_t) :: v
+  type(nested_t) :: n
+  !$acc parallel copy(p%x, p%y, v%arr, v%arr(1:5), n%pt%x)
+  p%x = 1.0
+  p%y = 2.0
+  v%arr(1) = p%x
+  n%pt%x = v%arr(1)
+  !$acc end parallel
+end subroutine
+
+subroutine test_default_none_component_covers_object()
+  use component_ref_types, only: nested_t, point_t, vec_t
+  type(point_t) :: p
+  type(vec_t) :: v
+  type(nested_t) :: n
+  !$acc parallel default(none) copy(p%x, v%arr(1:5), n%pt%x)
+  p%y = p%x
+  v%scale = v%arr(1)
+  n%tag = 1
+  !$acc end parallel
+end subroutine
+
+subroutine test_default_none_whole_object_covers_components()
+  use component_ref_types, only: point_t
+  type(point_t) :: p, q
+  !$acc parallel default(none) copy(p, q)
+  p%x = q%y
+  p = q
+  !$acc end parallel
+end subroutine
+
+subroutine test_default_none_unlisted_component_object()
+  use component_ref_types, only: point_t
+  type(point_t) :: p, q
+  !$acc parallel default(none) copy(p%x)
+  p%x = 1.0
+  !ERROR: The DEFAULT(NONE) clause requires that 'q' must be listed in a data-mapping clause
+  q%y = 2.0
+  !$acc end parallel
+end subroutine
+
+subroutine test_same_object_same_dsa_components()
+  use component_ref_types, only: point_t
+  type(point_t) :: p
+  integer :: i
+  !$acc parallel loop private(p%x, p%y, p%x)
+  do i = 1, 10
+    p%x = real(i)
+    p%y = p%x
+  end do
+  !$acc end parallel loop
+end subroutine
+
+subroutine test_same_object_incompatible_same_component()
+  use component_ref_types, only: point_t
+  type(point_t) :: p
+  integer :: i
+  !ERROR: 'p' appears in more than one data-sharing clause on the same OpenACC directive
+  !$acc parallel loop private(p%x) firstprivate(p%x)
+  do i = 1, 10
+    p%x = real(i)
+  end do
+  !$acc end parallel loop
+end subroutine
+
+subroutine test_same_object_incompatible_different_components()
+  use component_ref_types, only: point_t
+  type(point_t) :: p
+  integer :: i
+  !ERROR: 'p' appears in more than one data-sharing clause on the same OpenACC directive
+  !$acc parallel loop private(p%x) firstprivate(p%y)
+  do i = 1, 10
+    p%x = real(i)
+    p%y = p%x
+  end do
+  !$acc end parallel loop
+end subroutine
+
+subroutine test_whole_object_incompatible_with_component()
+  use component_ref_types, only: point_t
+  type(point_t) :: p
+  integer :: i
+  !ERROR: 'p' appears in more than one data-sharing clause on the same OpenACC directive
+  !$acc parallel loop private(p) firstprivate(p%x)
+  do i = 1, 10
+    p%x = real(i)
+  end do
+  !$acc end parallel loop
+end subroutine
+
+subroutine test_distinct_objects_same_type_same_component()
+  use component_ref_types, only: point_t
+  type(point_t) :: p, q
+  integer :: i
+  !$acc parallel loop default(none) private(p%x) firstprivate(q%x)
+  do i = 1, 10
+    p%x = q%x + real(i)
+  end do
+  !$acc end parallel loop
+end subroutine
+
+subroutine test_indexed_component_refs_are_not_conflicts()
+  use component_ref_types, only: vec_t
+  type(vec_t) :: v
+  integer :: i
+  !$acc parallel loop default(none) private(v%arr(1:5)) firstprivate(v%arr(6:10))
+  do i = 1, 10
+    v%arr(i) = real(i)
+  end do
+  !$acc end parallel loop
+end subroutine

>From 247ae4ffcfe6a9be60bc648217c1fc63cfbd23a0 Mon Sep 17 00:00:00 2001
From: Andre Kuhlenschmidt <akuhlenschmi at nvidia.com>
Date: Thu, 25 Jun 2026 16:56:02 -0700
Subject: [PATCH 3/3] [flang][openacc] Reject subcomponent refs in clauses

---
 flang/lib/Semantics/resolve-directives.cpp    | 48 ++++++++++---------
 ...declare-global-component-not-supported.f90 | 19 ++++----
 .../OpenACC/acc-component-ref-dsa.f90         | 37 ++++++++++----
 .../OpenACC/acc-dataclause-dedup.f90          |  4 +-
 4 files changed, 64 insertions(+), 44 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index d861f527bb10b..5f035c2588199 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1901,37 +1901,37 @@ void AccAttributeVisitor::ResolveAccObjectList(
   }
 }
 
-static bool IsBareNameOrComponentRef(const parser::DataRef &dataRef);
+static bool ContainsStructureComponent(const parser::DataRef &dataRef);
 
-static bool IsBareNameOrComponentRef(
-    const parser::StructureComponent &component) {
-  return IsBareNameOrComponentRef(component.Base());
-}
-
-static bool IsBareNameOrComponentRef(const parser::DataRef &dataRef) {
+static bool ContainsStructureComponent(const parser::DataRef &dataRef) {
   return common::visit(
       common::visitors{
-          [](const parser::Name &) { return true; },
-          [](const common::Indirection<parser::StructureComponent> &component) {
-            return IsBareNameOrComponentRef(component.value());
+          [](const parser::Name &) { return false; },
+          [](const common::Indirection<parser::StructureComponent> &) {
+            return true;
           },
-          [](const common::Indirection<parser::ArrayElement> &) {
-            return false;
+          [](const common::Indirection<parser::ArrayElement> &arrayElement) {
+            return ContainsStructureComponent(arrayElement.value().Base());
           },
-          [](const common::Indirection<parser::CoindexedNamedObject> &) {
-            return false;
+          [](const common::Indirection<parser::CoindexedNamedObject>
+                  &coindexed) {
+            return ContainsStructureComponent(
+                std::get<parser::DataRef>(coindexed.value().t));
           },
       },
       dataRef.u);
 }
 
-static bool IsBareNameOrComponentRef(const parser::Designator &designator) {
+static bool ContainsStructureComponent(const parser::Designator &designator) {
   return common::visit(
       common::visitors{
           [](const parser::DataRef &dataRef) {
-            return IsBareNameOrComponentRef(dataRef);
+            return ContainsStructureComponent(dataRef);
+          },
+          [](const parser::Substring &substring) {
+            return ContainsStructureComponent(
+                std::get<parser::DataRef>(substring.t));
           },
-          [](const parser::Substring &) { return false; },
       },
       designator.u);
 }
@@ -1941,9 +1941,9 @@ void AccAttributeVisitor::ResolveAccObject(
   common::visit(
       common::visitors{
           [&](const parser::Designator &designator) {
-            const bool isDataRef{
+            const bool preciseDesignator{
                 parser::GetDesignatorNameIfDataRef(designator) != nullptr};
-            if (!isDataRef) {
+            if (!preciseDesignator) {
               // Subscripted designator: evaluate subscripts and detect
               // the substring case that is disallowed in OpenACC clauses.
               if (AnalyzeExpr(context_, designator)) {
@@ -1955,6 +1955,11 @@ void AccAttributeVisitor::ResolveAccObject(
                 }
               }
             }
+            if (ContainsStructureComponent(designator)) {
+              context_.Say(designator.source,
+                  "OpenACC subcomponent references are not yet supported in clauses"_todo_en_US);
+              return;
+            }
             // GetFirstName extracts the base symbol from both bare data
             // references and array sections, unifying DSA registration so
             // that DEFAULT(NONE) checking does not spuriously flag variables
@@ -1964,10 +1969,9 @@ void AccAttributeVisitor::ResolveAccObject(
             const parser::Name &baseName{parser::GetFirstName(designator)};
             if (auto *symbol{ResolveAcc(baseName, accFlag, currScope())}) {
               AddToContextObjectWithDSA(*symbol, accFlag);
-              if (IsBareNameOrComponentRef(designator) &&
-                  dataSharingAttributeFlags.test(accFlag)) {
+              if (preciseDesignator && dataSharingAttributeFlags.test(accFlag)) {
                 CheckMultipleAppearances(
-                    baseName, *symbol, accFlag, &accObject, isDataRef);
+                    baseName, *symbol, accFlag, &accObject, preciseDesignator);
               }
             }
           },
diff --git a/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90 b/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90
index 3d872240e9525..58dd89ad89b00 100644
--- a/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90
+++ b/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90
@@ -1,17 +1,14 @@
-! Reject unsupported !$acc declare module structure component cases:
-! - `obj%vals` without the whole variable.
-! - Non-simple designators (array element base, chained `%`).
+! Reject unsupported !$acc declare module subcomponent cases.
 
 ! RUN: split-file %s %t
-! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_create_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-WHOLE
-! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_copyin_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-WHOLE
-! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_device_resident_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-WHOLE
-! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_link_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-WHOLE
-! RUN: not bbc -fopenacc -emit-hlfir %t/declare_array_element_component.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-TODO
-! RUN: not bbc -fopenacc -emit-hlfir %t/declare_nested_structure_components.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-TODO
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_create_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-SUBCOMPONENT
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_copyin_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-SUBCOMPONENT
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_device_resident_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-SUBCOMPONENT
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_link_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-SUBCOMPONENT
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_array_element_component.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-SUBCOMPONENT
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_nested_structure_components.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-SUBCOMPONENT
 
-! ERR-WHOLE: not yet implemented: OpenACC declare: whole variable must appear in ACC DECLARE before a component reference; list the whole variable in this or an earlier clause
-! ERR-TODO: not yet implemented: OpenACC declare does not support this component reference in a module; ACC DECLARE the whole variable instead
+! ERR-SUBCOMPONENT: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
 
 //--- declare_module_create_component_only.f90
 
diff --git a/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90 b/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90
index 1c651153339da..579cc75776e59 100644
--- a/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90
+++ b/flang/test/Semantics/OpenACC/acc-component-ref-dsa.f90
@@ -1,7 +1,7 @@
 ! RUN: %python %S/../test_errors.py %s %flang -fopenacc -fno-openacc-default-none-scalars-strict
 
-! Derived-type component references in OpenACC data clauses should register the
-! base object for DEFAULT(NONE) checking and for bare component DSA conflicts.
+! Derived-type component references in OpenACC clauses are not supported until
+! subcomponent data-sharing tracking is precise.
 
 module component_ref_types
   implicit none
@@ -24,6 +24,11 @@ subroutine test_component_clauses_are_accepted()
   type(point_t) :: p
   type(vec_t) :: v
   type(nested_t) :: n
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
   !$acc parallel copy(p%x, p%y, v%arr, v%arr(1:5), n%pt%x)
   p%x = 1.0
   p%y = 2.0
@@ -37,7 +42,10 @@ subroutine test_default_none_component_covers_object()
   type(point_t) :: p
   type(vec_t) :: v
   type(nested_t) :: n
-  !$acc parallel default(none) copy(p%x, v%arr(1:5), n%pt%x)
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !$acc parallel copy(p%x, v%arr(1:5), n%pt%x)
   p%y = p%x
   v%scale = v%arr(1)
   n%tag = 1
@@ -56,9 +64,9 @@ subroutine test_default_none_whole_object_covers_components()
 subroutine test_default_none_unlisted_component_object()
   use component_ref_types, only: point_t
   type(point_t) :: p, q
-  !$acc parallel default(none) copy(p%x)
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !$acc parallel copy(p%x)
   p%x = 1.0
-  !ERROR: The DEFAULT(NONE) clause requires that 'q' must be listed in a data-mapping clause
   q%y = 2.0
   !$acc end parallel
 end subroutine
@@ -67,6 +75,9 @@ subroutine test_same_object_same_dsa_components()
   use component_ref_types, only: point_t
   type(point_t) :: p
   integer :: i
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
   !$acc parallel loop private(p%x, p%y, p%x)
   do i = 1, 10
     p%x = real(i)
@@ -79,7 +90,8 @@ subroutine test_same_object_incompatible_same_component()
   use component_ref_types, only: point_t
   type(point_t) :: p
   integer :: i
-  !ERROR: 'p' appears in more than one data-sharing clause on the same OpenACC directive
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
   !$acc parallel loop private(p%x) firstprivate(p%x)
   do i = 1, 10
     p%x = real(i)
@@ -91,7 +103,8 @@ subroutine test_same_object_incompatible_different_components()
   use component_ref_types, only: point_t
   type(point_t) :: p
   integer :: i
-  !ERROR: 'p' appears in more than one data-sharing clause on the same OpenACC directive
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
   !$acc parallel loop private(p%x) firstprivate(p%y)
   do i = 1, 10
     p%x = real(i)
@@ -104,7 +117,7 @@ subroutine test_whole_object_incompatible_with_component()
   use component_ref_types, only: point_t
   type(point_t) :: p
   integer :: i
-  !ERROR: 'p' appears in more than one data-sharing clause on the same OpenACC directive
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
   !$acc parallel loop private(p) firstprivate(p%x)
   do i = 1, 10
     p%x = real(i)
@@ -116,7 +129,9 @@ subroutine test_distinct_objects_same_type_same_component()
   use component_ref_types, only: point_t
   type(point_t) :: p, q
   integer :: i
-  !$acc parallel loop default(none) private(p%x) firstprivate(q%x)
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !$acc parallel loop private(p%x) firstprivate(q%x)
   do i = 1, 10
     p%x = q%x + real(i)
   end do
@@ -127,7 +142,9 @@ subroutine test_indexed_component_refs_are_not_conflicts()
   use component_ref_types, only: vec_t
   type(vec_t) :: v
   integer :: i
-  !$acc parallel loop default(none) private(v%arr(1:5)) firstprivate(v%arr(6:10))
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+  !$acc parallel loop private(v%arr(1:5)) firstprivate(v%arr(6:10))
   do i = 1, 10
     v%arr(i) = real(i)
   end do
diff --git a/flang/test/Semantics/OpenACC/acc-dataclause-dedup.f90 b/flang/test/Semantics/OpenACC/acc-dataclause-dedup.f90
index e29332578a0bf..ea7c42fe50ace 100644
--- a/flang/test/Semantics/OpenACC/acc-dataclause-dedup.f90
+++ b/flang/test/Semantics/OpenACC/acc-dataclause-dedup.f90
@@ -106,7 +106,9 @@ program test_dataclause_dedup
     do i = 1, 10
     end do
 
-    ! Distinct structure components -- not duplicates.
+    ! Distinct structure components are rejected before duplicate checking.
+    !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
+    !ERROR: not yet implemented: OpenACC subcomponent references are not yet supported in clauses
     !$acc parallel loop private(s%a, s%b)
     do i = 1, 10
     end do



More information about the flang-commits mailing list