From 0e32339e1caddd969e072f8fdfa59aa803c29cc1 Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" Date: Fri, 19 Dec 2025 06:26:52 -0800 Subject: [PATCH] [clang] Accept non const static work_group_static variables in templates In general, SYCL doesn't allow non const static variables, but for some extensions like work_group_static it is allowed. This is done by checking presence of an attribute on the type of the variable. However detection of such cases worked incorrectly in template contexts since a dependent type may not yet have the attribute. This patch fixes the problem by not diagnosing variables with dependent types. --- clang/lib/Sema/SemaDecl.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 4 +++- clang/test/SemaSYCL/sycl_wg_scope.cpp | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ac78d2b68fd59..f3d8eb11ecd04 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8197,6 +8197,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( // constexpr unless their types are decorated with global_variable_allowed // attribute. if (SCSpec == DeclSpec::SCS_static && !R.isConstant(Context) && + !NewVD->getType()->isDependentType() && !SYCL().isTypeDecoratedWithDeclAttribute( NewVD->getType()) && !SYCL().isTypeDecoratedWithDeclAttribute( diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index dffdb8b97210b..e6311c930b125 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -228,7 +228,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, ObjCInterfaceDecl *ClassReceiver, bool SkipTrailingRequiresClause) { if (getLangOpts().SYCLIsDevice) { - if (auto VD = dyn_cast(D)) { + if (auto VD = dyn_cast(D); + VD && !VD->getType()->isDependentType()) { bool IsConst = VD->getType().isConstant(Context); bool IsRuntimeEvaluated = ExprEvalContexts.empty() || @@ -239,6 +240,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, if (IsRuntimeEvaluated && !IsEsimdPrivateGlobal && !IsConst && VD->getStorageClass() == SC_Static && !VD->hasAttr() && + !VD->getType()->isDependentType() && !SemaSYCL::isTypeDecoratedWithDeclAttribute< SYCLGlobalVariableAllowedAttr>(VD->getType()) && !SemaSYCL::isTypeDecoratedWithDeclAttribute( diff --git a/clang/test/SemaSYCL/sycl_wg_scope.cpp b/clang/test/SemaSYCL/sycl_wg_scope.cpp index 51f9616d47528..64f17cb27467e 100644 --- a/clang/test/SemaSYCL/sycl_wg_scope.cpp +++ b/clang/test/SemaSYCL/sycl_wg_scope.cpp @@ -58,6 +58,8 @@ template class [[__sycl_detail__::wg_scope]] B12 { // #B12 B12() = default; ~B12() = default; T obj; + operator T&() {return obj;} + T *operator&() noexcept { return &obj; } }; B12 b12; @@ -84,6 +86,19 @@ struct Wrap { static G1 g18; }; +template +struct MyClass { + static B12 slm; + T *ptr() { + return &slm; + } +}; + +template +void foo() { + static T m; +} + __attribute__((sycl_device)) void ref_func() { G1 g19; static G1 g20; @@ -91,4 +106,7 @@ __attribute__((sycl_device)) void ref_func() { (void)g16; (void)g17; (void)Wrap::g18; + MyClass<1, int> c1; + (void)c1.ptr(); + foo>(); }