[flang-commits] [flang] c91ab61 - [flang][acc] Disallow duplicate variables in use_device clause (#176217)

via flang-commits flang-commits at lists.llvm.org
Thu Jan 15 11:31:32 PST 2026


Author: Razvan Lupusoru
Date: 2026-01-15T19:31:27Z
New Revision: c91ab61de79368ec330fc15259f60e2365b539bd

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

LOG: [flang][acc] Disallow duplicate variables in use_device clause (#176217)

Add a semantic check to detect when the same variable appears multiple
times in `use_device` clauses on the same `host_data` directive. While
the OpenACC specification does not explicitly prohibit this, allowing
duplicates is likely a user error and provides no additional semantics.

A similar restriction was already in place for `private`,
`firstprivate`, and `reduction` clauses on compute constructs. This
change extends that behavior to `use_device` on `host_data`.

Error message:
`'<var>' appears in more than one USE_DEVICE clause on the same
HOST_DATA directive`

Added: 
    

Modified: 
    flang/docs/OpenACC.md
    flang/lib/Semantics/resolve-directives.cpp
    flang/test/Semantics/OpenACC/acc-host-data.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md
index f1fe69e57bf37..85e9430a203ec 100644
--- a/flang/docs/OpenACC.md
+++ b/flang/docs/OpenACC.md
@@ -30,6 +30,12 @@ local:
 * The OpenACC specification disallows a variable appearing multiple times in
   clauses of `!$acc declare` directives for a function, subroutine, program,
   or module, but it is allowed with a warning when same clause is used.
+* The OpenACC specification does not prohibit the same variable from appearing
+  in multiple data clauses, but this is disallowed for variables appearing in
+  `private`, `firstprivate`, or `reduction` clauses.
+* The OpenACC specification does not prohibit the same variable from appearing
+  multiple times in a `use_device` clause on a `host_data` construct, but this
+  is disallowed.
 
 ## Remarks about incompatibilities with other implementations
 * Array element references in the data clauses are equivalent to array sections

diff  --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 6467abf872c16..0ca84d84b97b6 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -334,6 +334,20 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
 
   bool Pre(const parser::AccClause::UseDevice &x) {
     ResolveAccObjectList(x.v, Symbol::Flag::AccUseDevice);
+    // use_device is only valid on host_data directive
+    assert(GetContext().directive == llvm::acc::Directive::ACCD_host_data &&
+        "use_device clause is only valid on host_data directive");
+    // Check for duplicate use_device variables
+    for (const auto &accObject : x.v.v) {
+      if (const auto *designator{
+              std::get_if<parser::Designator>(&accObject.u)}) {
+        if (const auto *name{parser::GetDesignatorNameIfDataRef(*designator)}) {
+          if (name->symbol) {
+            AddUseDeviceObject(*name->symbol, *name);
+          }
+        }
+      }
+    }
     return false;
   }
 
@@ -379,6 +393,13 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
       const llvm::acc::Clause clause, const parser::AccObjectList &objectList);
   void AddRoutineInfoToSymbol(
       Symbol &, const parser::OpenACCRoutineConstruct &);
+
+  // Track use_device variables and check for duplicates.
+  // Emits an error if the object was already added.
+  void AddUseDeviceObject(const Symbol &, const parser::Name &);
+  void ClearUseDeviceObjects() { useDeviceObjects_.clear(); }
+  UnorderedSymbolSet useDeviceObjects_;
+
   Scope *topScope_;
 };
 
@@ -1185,6 +1206,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCBlockConstruct &x) {
     break;
   }
   ClearDataSharingAttributeObjects();
+  ClearUseDeviceObjects();
   return true;
 }
 
@@ -1766,6 +1788,15 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   return nullptr;
 }
 
+void AccAttributeVisitor::AddUseDeviceObject(
+    const Symbol &object, const parser::Name &name) {
+  if (!useDeviceObjects_.insert(object).second) {
+    context_.Say(name.source,
+        "'%s' appears in more than one USE_DEVICE clause on the same HOST_DATA directive"_err_en_US,
+        name.ToString());
+  }
+}
+
 void AccAttributeVisitor::ResolveAccObjectList(
     const parser::AccObjectList &accObjectList, Symbol::Flag accFlag) {
   for (const auto &accObject : accObjectList.v) {

diff  --git a/flang/test/Semantics/OpenACC/acc-host-data.f90 b/flang/test/Semantics/OpenACC/acc-host-data.f90
index f5aa4d7f320ff..e6d76e373347b 100644
--- a/flang/test/Semantics/OpenACC/acc-host-data.f90
+++ b/flang/test/Semantics/OpenACC/acc-host-data.f90
@@ -38,4 +38,12 @@ program openacc_host_data_validity
   !$acc host_data use_device(aa, bb) if(.true.) if(ifCondition)
   !$acc end host_data
 
+  !ERROR: 'aa' appears in more than one USE_DEVICE clause on the same HOST_DATA directive
+  !$acc host_data use_device(aa) use_device(aa)
+  !$acc end host_data
+
+  !ERROR: 'bb' appears in more than one USE_DEVICE clause on the same HOST_DATA directive
+  !$acc host_data use_device(bb, bb)
+  !$acc end host_data
+
 end program openacc_host_data_validity


        


More information about the flang-commits mailing list