Skip to content

Commit 0d95702

Browse files
Artem-Btomtor
authored andcommitted
[CUDA] Disallow use of address_space(N) on CUDA device variables. (llvm#142857)
The variables have implicit host-side shadow instances and explicit address space attribute breaks them on the host.
1 parent 3f6e550 commit 0d95702

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9432,6 +9432,8 @@ def err_cuda_host_shared : Error<
94329432
"%select{__device__|__global__|__host__|__host__ __device__}0 functions">;
94339433
def err_cuda_nonstatic_constdev: Error<"__constant__, __device__, and "
94349434
"__managed__ are not allowed on non-static local variables">;
9435+
def err_cuda_address_space_gpuvar: Error<"__constant__, __device__, and "
9436+
"__shared__ variables must use default address space">;
94359437
def err_cuda_grid_constant_not_allowed : Error<
94369438
"__grid_constant__ is only allowed on const-qualified kernel parameters">;
94379439
def err_cuda_ovl_target : Error<

clang/lib/Sema/SemaCUDA.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ void SemaCUDA::EraseUnwantedMatches(
321321
if (Matches.size() <= 1)
322322
return;
323323

324-
using Pair = std::pair<DeclAccessPair, FunctionDecl*>;
324+
using Pair = std::pair<DeclAccessPair, FunctionDecl *>;
325325

326326
// Gets the CUDA function preference for a call from Caller to Match.
327327
auto GetCFP = [&](const Pair &Match) {
@@ -504,7 +504,6 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
504504
}
505505
}
506506

507-
508507
// If no target was inferred, mark this member as __host__ __device__;
509508
// it's the least restrictive option that can be invoked from any target.
510509
bool NeedsH = true, NeedsD = true;
@@ -679,16 +678,22 @@ void SemaCUDA::checkAllowedInitializer(VarDecl *VD) {
679678
FD && FD->isDependentContext())
680679
return;
681680

681+
bool IsSharedVar = VD->hasAttr<CUDASharedAttr>();
682+
bool IsDeviceOrConstantVar =
683+
!IsSharedVar &&
684+
(VD->hasAttr<CUDADeviceAttr>() || VD->hasAttr<CUDAConstantAttr>());
685+
if ((IsSharedVar || IsDeviceOrConstantVar) &&
686+
VD->getType().getQualifiers().getAddressSpace() != LangAS::Default) {
687+
Diag(VD->getLocation(), diag::err_cuda_address_space_gpuvar);
688+
VD->setInvalidDecl();
689+
return;
690+
}
682691
// Do not check dependent variables since the ctor/dtor/initializer are not
683692
// determined. Do it after instantiation.
684693
if (VD->isInvalidDecl() || !VD->hasInit() || !VD->hasGlobalStorage() ||
685694
IsDependentVar(VD))
686695
return;
687696
const Expr *Init = VD->getInit();
688-
bool IsSharedVar = VD->hasAttr<CUDASharedAttr>();
689-
bool IsDeviceOrConstantVar =
690-
!IsSharedVar &&
691-
(VD->hasAttr<CUDADeviceAttr>() || VD->hasAttr<CUDAConstantAttr>());
692697
if (IsDeviceOrConstantVar || IsSharedVar) {
693698
if (HasAllowedCUDADeviceStaticInitializer(
694699
*this, VD, IsSharedVar ? CICK_Shared : CICK_DeviceOrConstant))

clang/test/SemaCUDA/bad-attributes.cu

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ __global__ __device__ void z11(); // expected-error {{attributes are not compat
5050
__global__ __host__ void z12(); // expected-error {{attributes are not compatible}}
5151
// expected-note@-1 {{conflicting attribute is here}}
5252

53+
// Make sure GPU-side variables do not allow __attribute((address_space(N)))
54+
// expected-error@+1 {{__constant__, __device__, and __shared__ variables must use default address space}}
55+
__shared__ __attribute__((address_space(999))) int as_s;
56+
// expected-error@+1 {{__constant__, __device__, and __shared__ variables must use default address space}}
57+
__device__ __attribute__((address_space(999))) int as_d;
58+
// expected-error@+1 {{__constant__, __device__, and __shared__ variables must use default address space}}
59+
__constant__ __attribute__((address_space(999))) int as_c;
60+
5361
struct S {
5462
__global__ void foo() {}; // expected-error {{must be a free function or static member function}}
5563
__global__ static void bar(); // expected-warning {{kernel function 'bar' is a member function}}

0 commit comments

Comments
 (0)