[flang-commits] [flang] [flang][CUDA] Preserve data attrs on assignment RHS (PR #207849)

via flang-commits flang-commits at lists.llvm.org
Mon Jul 6 14:46:24 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Andre Kuhlenschmidt (akuhlens)

<details>
<summary>Changes</summary>

Treat a parenthesized variable as a source of CUDA data attributes when checking dummy/actual argument compatibility. Defined assignment parenthesizes non-VALUE RHS actuals to preserve value semantics, but the CUDA address space of the referenced data is unchanged by that materialization.

Add CUDA semantics coverage for a device RHS selected through defined assignment.

---
Full diff: https://github.com/llvm/llvm-project/pull/207849.diff


2 Files Affected:

- (modified) flang/lib/Semantics/check-call.cpp (+34-1) 
- (added) flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf (+34) 


``````````diff
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 16c1e166ded66..060459ea0d495 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -27,6 +27,37 @@ namespace characteristics = Fortran::evaluate::characteristics;
 
 namespace Fortran::semantics {
 
+template <typename A> static bool IsParenthesizedVariable(const A &) {
+  return false;
+}
+
+template <typename T>
+static bool IsParenthesizedVariable(const evaluate::Expr<T> &expr) {
+  if (const auto *parens{
+          evaluate::UnwrapExpr<evaluate::Parentheses<T>>(expr)}) {
+    return evaluate::IsVariable(parens->left());
+  }
+  return false;
+}
+
+template <evaluate::TypeCategory CAT>
+static bool IsParenthesizedVariable(
+    const evaluate::Expr<evaluate::SomeKind<CAT>> &expr) {
+  return common::visit(
+      [](const auto &x) { return IsParenthesizedVariable(x); }, expr.u);
+}
+
+static bool IsParenthesizedVariable(
+    const evaluate::Expr<evaluate::SomeType> &expr) {
+  return common::visit(
+      [](const auto &x) { return IsParenthesizedVariable(x); }, expr.u);
+}
+
+static bool IsVariableOrParenthesizedVariable(
+    const evaluate::Expr<evaluate::SomeType> &expr) {
+  return evaluate::IsVariable(expr) || IsParenthesizedVariable(expr);
+}
+
 void CheckImplicitInterfaceArgKeywords(
     const evaluate::ActualArgument &arg, parser::ContextualMessages &messages) {
   auto restorer{
@@ -1124,7 +1155,9 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
       !FindOpenACCConstructContaining(scope)) {
     std::optional<common::CUDADataAttr> actualDataAttr, dummyDataAttr;
     // For a%b%c, the last symbol with a CUDA data attribute wins
-    if (actualIsVariable) {
+    // Parentheses here mean expression/copy semantics, but CUDA address space
+    // attributes remain stable when a variable is materialized as a copy.
+    if (IsVariableOrParenthesizedVariable(actual)) {
       for (const Symbol &s : evaluate::GetSymbolVector(actual)) {
         if (const auto *object{s.detailsIf<ObjectEntityDetails>()}) {
           if (auto cudaAttr{object->cudaDataAttr()}) {
diff --git a/flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf b/flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf
new file mode 100644
index 0000000000000..bd0ab5f7c3068
--- /dev/null
+++ b/flang/test/Semantics/CUDA/cuf-defined-assignment-rhs.cuf
@@ -0,0 +1,34 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1
+
+module m
+  type box
+    integer :: n
+  end type
+
+  interface assignment(=)
+    module procedure assign_host
+    module procedure assign_device
+  end interface
+
+contains
+  subroutine assign_host(lhs, rhs)
+    type(box), intent(inout) :: lhs
+    real, intent(in) :: rhs(:)
+  end subroutine
+
+  subroutine assign_device(lhs, rhs)
+    type(box), intent(inout) :: lhs
+    real, device, intent(in) :: rhs(:)
+  end subroutine
+end module
+
+subroutine test
+  use m
+  type(box) :: lhs
+  real :: host(4)
+  real, device, allocatable :: dev(:)
+  allocate(dev(4))
+
+  lhs = host
+  lhs = dev
+end subroutine

``````````

</details>


https://github.com/llvm/llvm-project/pull/207849


More information about the flang-commits mailing list