[clang] [CUDA] Treat function-scope statics in device code as device variables (PR #222985)

Ambrose Leeb via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 10:50:47 PDT 2026


================
@@ -764,8 +764,26 @@ void SemaCUDA::checkAllowedInitializer(VarDecl *VD) {
   if (VD->isInvalidDecl() || !VD->hasInit() || !VD->hasGlobalStorage() ||
       IsDependentVar(VD))
     return;
+
+  // A function-scope static is a device variable when it is emitted on the
+  // device side, and has the same initialization restrictions.
+  CUDAVariableTarget VT = IdentifyTarget(VD);
+  const FunctionDecl *FD = VD->getDeclContext()->getEnclosingFunction();
+
+  // CVT_Both means the enclosing function is __host__ __device__, so the
+  // variable is emitted on both sides and only the device-side copy is
+  // restricted. Lambdas are implicitly HD and their statics are host variables.
+  const bool IsDeviceCopyOfHDStatic = VT == CVT_Both &&
+                                      getLangOpts().CUDAIsDevice && FD &&
+                                      !isImplicitHostDeviceFunction(FD);
+
+  // constexpr implies constant initialization and constant destruction.
+  bool IsDeviceLocalStatic = !IsSharedVar && VD->isStaticLocal() &&
+                             !VD->isConstexpr() &&
+                             (VT == CVT_Device || IsDeviceCopyOfHDStatic);
----------------
Sirraide wrote:

Does this end up skipping the check for statics in implicit `__host__ __device__` functions? It might be a better idea to diagnose otherwise unannotated `static` local variables specifically with `DiagIfDeviceCode()`. I believe that way, we would end up rejecting the definition if it actually ends up being used on the device side.

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


More information about the cfe-commits mailing list