[flang-commits] [flang] [flang][cuda][openacc] Reject UseDevice actual against managed/unified dummy (PR #196428)
via flang-commits
flang-commits at lists.llvm.org
Thu May 7 14:49:26 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Zhen Wang (wangzpgi)
<details>
<summary>Changes</summary>
After #<!-- -->195182 introduced the `UseDevice` attribute, a `use_device(...)` actual was treated as compatible with **any** dummy attribute. Combined with the matching distance returning ∞ for `UseDevice → managed/unified`, this caused generic resolution to misreport a clean "no match" as an **ambiguity** when only managed/unified specifics existed.
This PR tightens `AreCompatibleCUDADataAttrs`: a `UseDevice` actual is only compatible with a `Device` dummy or a host (no-attribute) dummy. Other attributes (`Managed`, `Unified`, `Pinned`, ...) require their actual to live in that specific kind of memory.
---
Full diff: https://github.com/llvm/llvm-project/pull/196428.diff
3 Files Affected:
- (modified) flang/lib/Semantics/expression.cpp (+2-9)
- (modified) flang/lib/Support/Fortran.cpp (+4-2)
- (modified) flang/test/Semantics/cuf27.cuf (+31)
``````````diff
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 8e09e6440a0b7..066ead7fc28e8 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -2943,20 +2943,13 @@ static int GetMatchingDistance(const common::LanguageFeatureControl &features,
// An actual argument with the UseDevice attribute comes from an OpenACC
// host_data use_device clause: the variable itself is host-resident, but
// inside the host_data region it is referenced via its device address.
- // It can therefore match either a host dummy or a device dummy in generic
- // resolution. The matching distance disambiguates when both kinds of
- // specifics exist:
- // - device dummy: 0 (best match: actual carries a device address)
- // - managed/unified dummy: 2 (acceptable: dummy is reachable from device)
- // - host dummy (no attr): 3 (acceptable: underlying variable is host)
+ // It matches a Device dummy with distance 0, a host dummy (no attribute)
+ // with distance 3, and is incompatible with any other dummy attribute.
if (actualDataAttr && *actualDataAttr == common::CUDADataAttr::UseDevice) {
if (!dummyDataAttr)
return 3;
if (*dummyDataAttr == common::CUDADataAttr::Device)
return 0;
- if (*dummyDataAttr == common::CUDADataAttr::Managed ||
- *dummyDataAttr == common::CUDADataAttr::Unified)
- return 2;
}
return cudaInfMatchingValue;
}
diff --git a/flang/lib/Support/Fortran.cpp b/flang/lib/Support/Fortran.cpp
index 267e227529332..d38e7dc051562 100644
--- a/flang/lib/Support/Fortran.cpp
+++ b/flang/lib/Support/Fortran.cpp
@@ -117,9 +117,11 @@ bool AreCompatibleCUDADataAttrs(std::optional<CUDADataAttr> x,
if (ignoreTKR.test(common::IgnoreTKR::Device)) {
return true;
}
- // A use_device(...) actual is compatible with any dummy.
+ // A use_device(...) actual is compatible only with a Device dummy or a
+ // host dummy (no CUDA attribute); other attributes (Managed, Unified,
+ // Pinned, ...) require the actual to live in that specific kind of memory.
if (y && *y == CUDADataAttr::UseDevice)
- return true;
+ return !x || *x == CUDADataAttr::Device;
if (!y && isHostDeviceProcedure) {
return true;
}
diff --git a/flang/test/Semantics/cuf27.cuf b/flang/test/Semantics/cuf27.cuf
index a3312f86247ab..62c2ace292997 100644
--- a/flang/test/Semantics/cuf27.cuf
+++ b/flang/test/Semantics/cuf27.cuf
@@ -83,3 +83,34 @@ subroutine test_use_device_pinned_use_assoc()
!$acc exit data delete(vkb)
deallocate(vkb, c_d, v_d)
end
+
+! When the generic offers only managed/unified specifics (no device or host
+! specific), a use_device actual must not match either: managed and unified
+! dummies require their actual to live in managed/unified memory, which a
+! use_device actual does not. The call should be rejected.
+module m4
+ interface overl_mu
+ module procedure overl_managed
+ module procedure overl_unified
+ end interface
+contains
+ subroutine overl_managed(x)
+ integer, managed :: x(:)
+ end subroutine
+ subroutine overl_unified(x)
+ integer, unified :: x(:)
+ end subroutine
+end module m4
+
+subroutine test_use_device_managed_unified_only()
+ use m4
+ integer, allocatable :: fx(:)
+ allocate(fx(100))
+ !$acc data copy(fx)
+ !$acc host_data use_device(fx)
+ !ERROR: No specific subroutine of generic 'overl_mu' matches the actual arguments
+ call overl_mu(fx)
+ !$acc end host_data
+ !$acc end data
+ deallocate(fx)
+end
``````````
</details>
https://github.com/llvm/llvm-project/pull/196428
More information about the flang-commits
mailing list