Skip to content

Conversation

@clementval
Copy link
Contributor

This can lead to segfault if a device variable is used in a host intrinsic. Emit an error in semantic.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:semantics labels Dec 18, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 18, 2025

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-fir-hlfir

Author: Valentin Clement (バレンタイン クレメン) (clementval)

Changes

This can lead to segfault if a device variable is used in a host intrinsic. Emit an error in semantic.


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

7 Files Affected:

  • (modified) flang/include/flang/Semantics/scope.h (+1-1)
  • (modified) flang/include/flang/Semantics/tools.h (+1)
  • (modified) flang/lib/Semantics/check-call.cpp (+31)
  • (modified) flang/lib/Semantics/resolve-names.cpp (+11)
  • (modified) flang/lib/Semantics/tools.cpp (+8)
  • (modified) flang/test/Lower/CUDA/cuda-data-transfer.cuf (+11-1)
  • (modified) flang/test/Semantics/cuf23.cuf (+7)
diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index ecffdb468bf6c..25806fafc689a 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -61,7 +61,7 @@ class Scope {
 public:
   ENUM_CLASS(Kind, Global, IntrinsicModules, Module, MainProgram, Subprogram,
       BlockData, DerivedType, BlockConstruct, Forall, OtherConstruct,
-      OpenACCConstruct, ImpliedDos, OtherClause)
+      OpenACCConstruct, ImpliedDos, OtherClause, CUFKernelDoConstruct)
   using ImportKind = common::ImportKind;
 
   // Create the Global scope -- the root of the scope tree
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index 1c3477013b559..1ea40bbb43e61 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -46,6 +46,7 @@ const Scope *FindModuleOrSubmoduleContaining(const Scope &);
 const Scope *FindModuleFileContaining(const Scope &);
 const Scope *FindPureProcedureContaining(const Scope &);
 const Scope *FindOpenACCConstructContaining(const Scope *);
+const Scope *FindCUFKernelDoConstructContaining(const Scope *);
 
 const Symbol *FindInterface(const Symbol &);
 const Symbol *FindSubprogram(const Symbol &);
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 022b4289b4e7c..2bf1d41e4e449 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -1145,6 +1145,37 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
           dummyName, toStr(dummyDataAttr), toStr(actualDataAttr));
     }
   }
+  // Emit an error message if an actual argument passed to a host intrinsic is
+  // on the device.
+  if (intrinsic && !FindCUDADeviceContext(scope) &&
+      !FindOpenACCConstructContaining(scope) &&
+      !FindCUFKernelDoConstructContaining(scope)) {
+    if (intrinsic->name != "__builtin_c_f_pointer" &&
+        intrinsic->name != "__builtin_c_loc") {
+      std::optional<common::CUDADataAttr> actualDataAttr;
+      if (const auto *actualObject{actualLastSymbol
+                  ? actualLastSymbol->detailsIf<ObjectEntityDetails>()
+                  : nullptr}) {
+        actualDataAttr = actualObject->cudaDataAttr();
+      }
+      if (actualDataAttr && *actualDataAttr == common::CUDADataAttr::Device) {
+        // Allocatable or pointer with device attribute have their descriptor in
+        // managed memory. It is allowed to pass them to some inquiry
+        // intrinsics.
+        if (!actualLastSymbol || !IsAllocatableOrPointer(*actualLastSymbol) ||
+            (IsAllocatableOrPointer(*actualLastSymbol) &&
+                intrinsic->name != "size" && intrinsic->name != "lbound" &&
+                intrinsic->name != "ubound" && intrinsic->name != "shape" &&
+                intrinsic->name != "allocated" &&
+                intrinsic->name != "associated" && intrinsic->name != "kind" &&
+                intrinsic->name != "present")) {
+          messages.Say(
+              "Actual argument %s associated with host intrinsic %s is on the device"_err_en_US,
+              actualLastSymbol->name(), intrinsic->name);
+        }
+      }
+    }
+  }
 
   // Warning for breaking F'2023 change with character allocatables
   if (intrinsic && dummy.intent != common::Intent::In) {
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 345a0e4e8ecce..a7c5d5c3ca317 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1081,6 +1081,8 @@ class DeclarationVisitor : public ArraySpecVisitor,
   bool Pre(const parser::SaveStmt &);
   bool Pre(const parser::BasedPointer &);
   void Post(const parser::BasedPointer &);
+  bool Pre(const parser::CUFKernelDoConstruct &);
+  void Post(const parser::CUFKernelDoConstruct &);
 
   void PointerInitialization(
       const parser::Name &, const parser::InitialDataTarget &);
@@ -9257,6 +9259,15 @@ void DeclarationVisitor::LegacyDataInitialization(const parser::Name &name,
   }
 }
 
+bool DeclarationVisitor::Pre(const parser::CUFKernelDoConstruct &x) {
+  PushScope(Scope::Kind::CUFKernelDoConstruct, nullptr);
+  return true;
+}
+
+void DeclarationVisitor::Post(const parser::CUFKernelDoConstruct &x) {
+  PopScope();
+}
+
 void ResolveNamesVisitor::HandleCall(
     Symbol::Flag procFlag, const parser::Call &call) {
   common::visit(
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index cf1e5e7d44565..c1d7c288d27f7 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -122,6 +122,14 @@ const Scope *FindOpenACCConstructContaining(const Scope *scope) {
                : nullptr;
 }
 
+const Scope *FindCUFKernelDoConstructContaining(const Scope *scope) {
+  return scope ? FindScopeContaining(*scope,
+                     [](const Scope &s) {
+                       return s.kind() == Scope::Kind::CUFKernelDoConstruct;
+                     })
+               : nullptr;
+}
+
 // 7.5.2.4 "same derived type" test -- rely on IsTkCompatibleWith() and its
 // infrastructure to detect and handle comparisons on distinct (but "same")
 // sequence/bind(C) derived types
diff --git a/flang/test/Lower/CUDA/cuda-data-transfer.cuf b/flang/test/Lower/CUDA/cuda-data-transfer.cuf
index 015947430b07c..e0c23a1d5df8f 100644
--- a/flang/test/Lower/CUDA/cuda-data-transfer.cuf
+++ b/flang/test/Lower/CUDA/cuda-data-transfer.cuf
@@ -22,6 +22,15 @@ module mod1
     end function
   end interface
 
+  interface
+    function somefunction(d, n)
+      integer :: n
+      real(8), device :: d(n,n)
+      real(8) :: somefunction(n)
+    end function
+  end interface
+      
+
 contains
   function dev1(a)
     integer, device :: a(:)
@@ -447,9 +456,10 @@ end subroutine
 ! CHECK: cuf.data_transfer
 
 subroutine sub23(n)
+  use mod1
   integer :: n
   real(8), device :: d(n,n), x(n)
-  x = sum(d,dim=2) ! Was triggering Unsupported CUDA data transfer
+  x = somefunction(d,2) ! Was triggering Unsupported CUDA data transfer
 end subroutine
 
 ! CHECK-LABEL: func.func @_QPsub23
diff --git a/flang/test/Semantics/cuf23.cuf b/flang/test/Semantics/cuf23.cuf
index 8c03c18d9b0db..73f13d1d46a17 100644
--- a/flang/test/Semantics/cuf23.cuf
+++ b/flang/test/Semantics/cuf23.cuf
@@ -53,3 +53,10 @@ attributes(global) subroutine global_with_block()
     print*, a ! ok
   end block
 end subroutine
+
+subroutine intrinsic_error(n)
+  integer :: n
+  real(8), device :: d(n,n), x(n)
+!ERROR: Actual argument d associated with host intrinsic sum is on the device
+  x = sum(d,dim=2)
+end subroutine

@github-actions
Copy link

github-actions bot commented Dec 18, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@ergawy ergawy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for taking care of my comment.

@clementval clementval merged commit 68a0b93 into llvm:main Dec 30, 2025
10 checks passed
@clementval clementval deleted the cuf_host_intrinsic_error branch December 30, 2025 16:56
clementval added a commit that referenced this pull request Dec 30, 2025
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Dec 30, 2025
clementval added a commit to clementval/llvm-project that referenced this pull request Dec 30, 2025
…t intrinsic (llvm#172914)

This can lead to segfault if a device variable is used in a host
intrinsic. Emit an error in semantic.
clementval added a commit to clementval/llvm-project that referenced this pull request Dec 31, 2025
…t intrinsic (llvm#172914)

This can lead to segfault if a device variable is used in a host
intrinsic. Emit an error in semantic.
clementval added a commit to clementval/llvm-project that referenced this pull request Jan 2, 2026
…t intrinsic (llvm#172914)

This can lead to segfault if a device variable is used in a host
intrinsic. Emit an error in semantic.
clementval added a commit that referenced this pull request Jan 2, 2026
…t intrinsic (#174025)

This can lead to segfault if a device variable is used in a host
intrinsic. Emit an error in semantic.

Reland #172914 with the addition of `__builtin_c_devloc `, `loc` and
`present` as skipped intrinsic
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Jan 6, 2026
…t intrinsic (llvm#172914)

This can lead to segfault if a device variable is used in a host
intrinsic. Emit an error in semantic.
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Jan 6, 2026
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Jan 6, 2026
…t intrinsic (llvm#174025)

This can lead to segfault if a device variable is used in a host
intrinsic. Emit an error in semantic.

Reland llvm#172914 with the addition of `__builtin_c_devloc `, `loc` and
`present` as skipped intrinsic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang:semantics flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants