diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1079,6 +1079,7 @@ let LangOpts = [CUDA]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [CUDADeviceBuiltinSurfaceTypeDocs]; + let MeaningfulToClassTemplateDefinition = 1; } def CUDADeviceBuiltinTextureType : InheritableAttr { @@ -1087,6 +1088,7 @@ let LangOpts = [CUDA]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [CUDADeviceBuiltinTextureTypeDocs]; + let MeaningfulToClassTemplateDefinition = 1; } def CUDAGlobal : InheritableAttr { diff --git a/clang/test/SemaCUDA/device-use-host-var.cu b/clang/test/SemaCUDA/device-use-host-var.cu --- a/clang/test/SemaCUDA/device-use-host-var.cu +++ b/clang/test/SemaCUDA/device-use-host-var.cu @@ -158,3 +158,23 @@ }); } +// Texture references are special. As far as C++ is concerned they are host +// variables that are referenced from device code. However, they are handled +// very differently by the compiler under the hood and such references are +// allowed. Compiler should produce no warning here, but it should diagnose the +// same case without the device_builtin_texture_type attribute. +template +struct __attribute__((device_builtin_texture_type)) texture { + static texture ref; + __device__ int c() { + auto &x = ref; + } +}; + +template +struct not_a_texture { + static not_a_texture ref; + __device__ int c() { + auto &x = ref; // dev-error {{reference to __host__ variable 'ref' in __device__ function}} + } +};