[flang-commits] [flang] [flang][acc] Disallow duplicate variables in use_device clause (PR #176217)
Razvan Lupusoru via flang-commits
flang-commits at lists.llvm.org
Thu Jan 15 10:34:46 PST 2026
https://github.com/razvanlupusoru created https://github.com/llvm/llvm-project/pull/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"
>From a6ee4e0c7530b16a4bfd43a6ac8408e87ef541dc Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Thu, 15 Jan 2026 10:33:06 -0800
Subject: [PATCH] [flang][acc] Disallow duplicate variables in use_device
clause
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"
---
flang/docs/OpenACC.md | 6 ++++
flang/lib/Semantics/resolve-directives.cpp | 32 +++++++++++++++++++
.../test/Semantics/OpenACC/acc-host-data.f90 | 8 +++++
3 files changed, 46 insertions(+)
diff --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md
index f1fe69e57bf37..a83c6b233152a 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 disallow 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 disallow 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..48793e6c08319 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -334,6 +334,28 @@ 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) {
+ if (HasUseDeviceObject(*name->symbol)) {
+ context_.Say(name->source,
+ "'%s' appears in more than one USE_DEVICE clause "
+ "on the same HOST_DATA directive"_err_en_US,
+ name->ToString());
+ } else {
+ AddUseDeviceObject(*name->symbol);
+ }
+ }
+ }
+ }
+ }
return false;
}
@@ -379,6 +401,15 @@ 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
+ void AddUseDeviceObject(SymbolRef object) { useDeviceObjects_.insert(object); }
+ void ClearUseDeviceObjects() { useDeviceObjects_.clear(); }
+ bool HasUseDeviceObject(const Symbol &object) {
+ return useDeviceObjects_.find(object) != useDeviceObjects_.end();
+ }
+ UnorderedSymbolSet useDeviceObjects_;
+
Scope *topScope_;
};
@@ -1185,6 +1216,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCBlockConstruct &x) {
break;
}
ClearDataSharingAttributeObjects();
+ ClearUseDeviceObjects();
return true;
}
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