1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
|
// RUN: %clang_cc1 -std=c++11 -fcuda-is-device -fsyntax-only -verify=dev %s
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify=host %s
// host-no-diagnostics
#include "Inputs/cuda.h"
int func();
struct A {
int x;
static int host_var;
};
int A::host_var; // dev-note {{host variable declared here}}
namespace X {
int host_var; // dev-note {{host variable declared here}}
}
// struct with non-empty ctor.
struct B1 {
int x;
B1() { x = 1; }
};
// struct with non-empty dtor.
struct B2 {
int x;
B2() {}
~B2() { x = 0; }
};
static int static_host_var; // dev-note {{host variable declared here}}
__device__ int global_dev_var;
__constant__ int global_constant_var;
__shared__ int global_shared_var;
int global_host_var; // dev-note 8{{host variable declared here}}
const int global_const_var = 1;
constexpr int global_constexpr_var = 1;
int global_host_array[2] = {1, 2}; // dev-note {{host variable declared here}}
const int global_const_array[2] = {1, 2};
constexpr int global_constexpr_array[2] = {1, 2};
A global_host_struct_var{1}; // dev-note 2{{host variable declared here}}
const A global_const_struct_var{1};
constexpr A global_constexpr_struct_var{1};
// Check const host var initialized with non-empty ctor is not allowed in
// device function.
const B1 b1; // dev-note {{const variable cannot be emitted on device side due to dynamic initialization}}
// Check const host var having non-empty dtor is not allowed in device function.
const B2 b2; // dev-note {{const variable cannot be emitted on device side due to dynamic initialization}}
// Check const host var initialized by non-constant initializer is not allowed
// in device function.
const int b3 = func(); // dev-note {{const variable cannot be emitted on device side due to dynamic initialization}}
template<typename F>
__global__ void kernel(F f) { f(); } // dev-note2 {{called by 'kernel<(lambda}}
__device__ void dev_fun(int *out) {
// Check access device variables are allowed.
int &ref_dev_var = global_dev_var;
int &ref_constant_var = global_constant_var;
int &ref_shared_var = global_shared_var;
*out = ref_dev_var;
*out = ref_constant_var;
*out = ref_shared_var;
*out = global_dev_var;
*out = global_constant_var;
*out = global_shared_var;
// Check access of non-const host variables are not allowed.
*out = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __device__ function}}
*out = global_const_var;
*out = global_constexpr_var;
*out = b1.x; // dev-error {{reference to __host__ variable 'b1' in __device__ function}}
*out = b2.x; // dev-error {{reference to __host__ variable 'b2' in __device__ function}}
*out = b3; // dev-error {{reference to __host__ variable 'b3' in __device__ function}}
global_host_var = 1; // dev-error {{reference to __host__ variable 'global_host_var' in __device__ function}}
// Check reference of non-constexpr host variables are not allowed.
int &ref_host_var = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __device__ function}}
const int &ref_const_var = global_const_var;
const int &ref_constexpr_var = global_constexpr_var;
*out = ref_host_var;
*out = ref_constexpr_var;
*out = ref_const_var;
// Check access member of non-constexpr struct type host variable is not allowed.
*out = global_host_struct_var.x; // dev-error {{reference to __host__ variable 'global_host_struct_var' in __device__ function}}
*out = global_const_struct_var.x;
*out = global_constexpr_struct_var.x;
global_host_struct_var.x = 1; // dev-error {{reference to __host__ variable 'global_host_struct_var' in __device__ function}}
// Check address taking of non-constexpr host variables is not allowed.
int *p = &global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __device__ function}}
const int *cp = &global_const_var;
const int *cp2 = &global_constexpr_var;
// Check access elements of non-constexpr host array is not allowed.
*out = global_host_array[1]; // dev-error {{reference to __host__ variable 'global_host_array' in __device__ function}}
*out = global_const_array[1];
*out = global_constexpr_array[1];
// Check ODR-use of host variables in namespace is not allowed.
*out = X::host_var; // dev-error {{reference to __host__ variable 'host_var' in __device__ function}}
// Check ODR-use of static host varables in class or file scope is not allowed.
*out = A::host_var; // dev-error {{reference to __host__ variable 'host_var' in __device__ function}}
*out = static_host_var; // dev-error {{reference to __host__ variable 'static_host_var' in __device__ function}}
// Check function-scope static variable is allowed.
static int static_var;
*out = static_var;
// Check non-ODR use of host varirables are allowed.
*out = sizeof(global_host_var);
*out = sizeof(global_host_struct_var.x);
decltype(global_host_var) var1;
decltype(global_host_struct_var.x) var2;
}
__global__ void global_fun(int *out) {
int &ref_host_var = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __global__ function}}
int &ref_dev_var = global_dev_var;
int &ref_constant_var = global_constant_var;
int &ref_shared_var = global_shared_var;
const int &ref_constexpr_var = global_constexpr_var;
const int &ref_const_var = global_const_var;
*out = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __global__ function}}
*out = global_dev_var;
*out = global_constant_var;
*out = global_shared_var;
*out = global_constexpr_var;
*out = global_const_var;
*out = ref_host_var;
*out = ref_dev_var;
*out = ref_constant_var;
*out = ref_shared_var;
*out = ref_constexpr_var;
*out = ref_const_var;
}
__host__ __device__ void host_dev_fun(int *out) {
int &ref_host_var = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __host__ __device__ function}}
int &ref_dev_var = global_dev_var;
int &ref_constant_var = global_constant_var;
int &ref_shared_var = global_shared_var;
const int &ref_constexpr_var = global_constexpr_var;
const int &ref_const_var = global_const_var;
*out = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __host__ __device__ function}}
*out = global_dev_var;
*out = global_constant_var;
*out = global_shared_var;
*out = global_constexpr_var;
*out = global_const_var;
*out = ref_host_var;
*out = ref_dev_var;
*out = ref_constant_var;
*out = ref_shared_var;
*out = ref_constexpr_var;
*out = ref_const_var;
}
inline __host__ __device__ void inline_host_dev_fun(int *out) {
int &ref_host_var = global_host_var;
int &ref_dev_var = global_dev_var;
int &ref_constant_var = global_constant_var;
int &ref_shared_var = global_shared_var;
const int &ref_constexpr_var = global_constexpr_var;
const int &ref_const_var = global_const_var;
*out = global_host_var;
*out = global_dev_var;
*out = global_constant_var;
*out = global_shared_var;
*out = global_constexpr_var;
*out = global_const_var;
*out = ref_host_var;
*out = ref_dev_var;
*out = ref_constant_var;
*out = ref_shared_var;
*out = ref_constexpr_var;
*out = ref_const_var;
}
void dev_lambda_capture_by_ref(int *out) {
int &ref_host_var = global_host_var;
kernel<<<1,1>>>([&]() {
int &ref_dev_var = global_dev_var;
int &ref_constant_var = global_constant_var;
int &ref_shared_var = global_shared_var;
const int &ref_constexpr_var = global_constexpr_var;
const int &ref_const_var = global_const_var;
*out = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __host__ __device__ function}}
// dev-error@-1 {{capture host variable 'out' by reference in device or host device lambda function}}
*out = global_dev_var;
*out = global_constant_var;
*out = global_shared_var;
*out = global_constexpr_var;
*out = global_const_var;
*out = ref_host_var; // dev-error {{capture host variable 'ref_host_var' by reference in device or host device lambda function}}
*out = ref_dev_var;
*out = ref_constant_var;
*out = ref_shared_var;
*out = ref_constexpr_var;
*out = ref_const_var;
});
}
void dev_lambda_capture_by_copy(int *out) {
int &ref_host_var = global_host_var;
kernel<<<1,1>>>([=]() {
int &ref_dev_var = global_dev_var;
int &ref_constant_var = global_constant_var;
int &ref_shared_var = global_shared_var;
const int &ref_constexpr_var = global_constexpr_var;
const int &ref_const_var = global_const_var;
*out = global_host_var; // dev-error {{reference to __host__ variable 'global_host_var' in __host__ __device__ function}}
*out = global_dev_var;
*out = global_constant_var;
*out = global_shared_var;
*out = global_constexpr_var;
*out = global_const_var;
*out = ref_host_var;
*out = ref_dev_var;
*out = ref_constant_var;
*out = ref_shared_var;
*out = ref_constexpr_var;
*out = ref_const_var;
});
}
// 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 <class, int = 1, int = 1>
struct __attribute__((device_builtin_texture_type)) texture {
static texture<int> ref;
__device__ void c() {
auto &x = ref;
}
};
template <class, int = 1, int = 1>
struct not_a_texture {
static not_a_texture<int> ref;
__device__ void c() {
auto &x = ref; // dev-error {{reference to __host__ variable 'ref' in __device__ function}}
}
};
template<>
not_a_texture<int> not_a_texture<int>::ref; // dev-note {{host variable declared here}}
__device__ void test_not_a_texture() {
not_a_texture<int> inst;
inst.c(); // dev-note {{in instantiation of member function 'not_a_texture<int, 1, 1>::c' requested here}}
}
// Test static variable in host function used by device function.
void test_static_var_host() {
for (int i = 0; i < 10; i++) {
static int x; // dev-note {{host variable declared here}}
struct A {
__device__ int f() {
return x; // dev-error{{reference to __host__ variable 'x' in __device__ function}}
}
};
}
}
// Test static variable in device function used by device function.
__device__ void test_static_var_device() {
for (int i = 0; i < 10; i++) {
static int x;
int y = x;
struct A {
__device__ int f() {
return x;
}
};
}
}
|