diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp index 318174f7be8fa..6a66ecf6f94c1 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -225,6 +225,15 @@ Sema::CUDAFunctionPreference Sema::IdentifyCUDAPreference(const FunctionDecl *Caller, const FunctionDecl *Callee) { assert(Callee && "Callee must be valid."); + + // Treat ctor/dtor as host device function in device var initializer to allow + // trivial ctor/dtor without device attr to be used. Non-trivial ctor/dtor + // will be diagnosed by checkAllowedCUDAInitializer. + if (Caller == nullptr && CurCUDATargetCtx.Kind == CTCK_InitGlobalVar && + CurCUDATargetCtx.Target == CFT_Device && + (isa(Callee) || isa(Callee))) + return CFP_HostDevice; + CUDAFunctionTarget CallerTarget = IdentifyCUDATarget(Caller); CUDAFunctionTarget CalleeTarget = IdentifyCUDATarget(Callee); diff --git a/clang/test/SemaCUDA/trivial-ctor-dtor.cu b/clang/test/SemaCUDA/trivial-ctor-dtor.cu new file mode 100644 index 0000000000000..34142bcc62120 --- /dev/null +++ b/clang/test/SemaCUDA/trivial-ctor-dtor.cu @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -isystem %S/Inputs -fsyntax-only -verify %s +// RUN: %clang_cc1 -isystem %S/Inputs -fcuda-is-device -fsyntax-only -verify %s + +#include + +// Check trivial ctor/dtor +struct A { + int x; + A() {} + ~A() {} +}; + +__device__ A a; + +// Check trivial ctor/dtor of template class +template +struct TA { + T x; + TA() {} + ~TA() {} +}; + +__device__ TA ta; + +// Check non-trivial ctor/dtor in parent template class +template +struct TB { + T x; + TB() { static int nontrivial_ctor = 1; } + ~TB() {} +}; + +template +struct TC : TB { + T x; + TC() {} + ~TC() {} +}; + +template class TC; + +__device__ TC tc; //expected-error {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} + +// Check trivial ctor specialization +template +struct C { + explicit C() {}; +}; + +template <> C::C() {}; +__device__ C ci_d; +C ci_h; + +// Check non-trivial ctor specialization +template <> C::C() { static int nontrivial_ctor = 1; } +__device__ C cf_d; //expected-error {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} +C cf_h;