// RUN: %clang_cc1 %s -verify=expected -pedantic -fsyntax-only
// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify=expected -pedantic -fsyntax-only
// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -verify=expected -pedantic -fsyntax-only
// RUN: %clang_cc1 %s -cl-std=clc++1.0 -verify -pedantic -fsyntax-only
// RUN: %clang_cc1 %s -cl-std=clc++2021 -cl-ext=+__opencl_c_generic_address_space -verify -pedantic -fsyntax-only
__constant int ci = 1;
// __constant ints are allowed in constant expressions.
enum use_ci_in_enum { enumerator = ci };
typedef int use_ci_in_array_bound[ci];
// general constant folding of array bounds is not permitted
typedef int folding_in_array_bounds[&ci + 3 - &ci]; // expected-error-re {{{{variable length arrays are not supported in OpenCL|array size is not a constant expression}}}} expected-note {{cannot refer to element 3}}
__kernel void foo {
__local int li;
__local int lj = 2; // expected-error {{'__local' variable cannot have an initializer}}
int *ip;
#if
ip = gip; // expected-error {{assigning '__global int *__private' to '__private int *__private' changes address space of pointer}}
ip = &li; // expected-error {{assigning '__local int *' to '__private int *__private' changes address space of pointer}}
ip = &ci; // expected-error {{assigning '__constant int *' to '__private int *__private' changes address space of pointer}}
#else
ip = gip;
ip = &li;
ip = &ci;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{assigning '__constant int *' to '__generic int *__private' changes address space of pointer}}
#else
// expected-error@-4 {{assigning '__constant int *' to '__generic int *' changes address space of pointer}}
#endif
#endif
}
void explicit_cast {
g = l;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__local int *' to type '__global int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__local int *' to '__global int *' converts between mismatching address spaces}}
#endif
g = c;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__constant int *' to type '__global int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__constant int *' to '__global int *' converts between mismatching address spaces}}
#endif
g = cc;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting 'const __constant int *' to type '__global int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from 'const __constant int *' to '__global int *' converts between mismatching address spaces}}
#endif
g = p;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__private int *' to type '__global int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__private int *' to '__global int *' converts between mismatching address spaces}}
#endif
l = g;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__global int *' to type '__local int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__global int *' to '__local int *' converts between mismatching address spaces}}
#endif
l = c;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__constant int *' to type '__local int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__constant int *' to '__local int *' converts between mismatching address spaces}}
#endif
l = cc;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting 'const __constant int *' to type '__local int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from 'const __constant int *' to '__local int *' converts between mismatching address spaces}}
#endif
l = p;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__private int *' to type '__local int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__private int *' to '__local int *' converts between mismatching address spaces}}
#endif
c = g;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__global int *' to type '__constant int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__global int *' to '__constant int *' converts between mismatching address spaces}}
#endif
c = l;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__local int *' to type '__constant int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__local int *' to '__constant int *' converts between mismatching address spaces}}
#endif
c = p;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__private int *' to type '__constant int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__private int *' to '__constant int *' converts between mismatching address spaces}}
#endif
p = g;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__global int *' to type '__private int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__global int *' to '__private int *' converts between mismatching address spaces}}
#endif
p = l;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__local int *' to type '__private int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__local int *' to '__private int *' converts between mismatching address spaces}}
#endif
p = c;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting '__constant int *' to type '__private int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from '__constant int *' to '__private int *' converts between mismatching address spaces}}
#endif
p = cc;
#if !__OPENCL_CPP_VERSION__
// expected-error@-2 {{casting 'const __constant int *' to type '__private int *' changes address space of pointer}}
#else
// expected-error@-4 {{C-style cast from 'const __constant int *' to '__private int *' converts between mismatching address spaces}}
#endif
}
void ok_explicit_casts {
g = g2;
l = l2;
p = p2;
}
#if !__OPENCL_CPP_VERSION__
void nested {
g = gg; // expected-error {{assigning '__global int *__private *__private' to '__global int *__private' changes address space of pointer}}
g = l; // expected-error {{assigning '__local int *__private' to '__global int *__private' changes address space of pointer}}
g = ll; // expected-error {{assigning '__local int *__private *__private' to '__global int *__private' changes address space of pointer}}
g = gg_f; // expected-error {{assigning '__global float *__private *__private' to '__global int *__private' changes address space of pointer}}
g = gg_f; // expected-error {{casting '__global float *__private *' to type '__global int *' changes address space of pointer}}
gg = g; // expected-error {{assigning '__global int *__private' to '__global int *__private *__private' changes address space of pointer}}
gg = l; // expected-error {{assigning '__local int *__private' to '__global int *__private *__private' changes address space of pointer}}
gg = ll; // expected-error {{assigning '__local int *__private *__private' to '__global int *__private *__private' changes address space of nested pointer}}
gg = gg_f; // expected-warning {{incompatible pointer types assigning to '__global int *__private *__private' from '__global float *__private *__private'}}
gg = gg_f;
l = g; // expected-error {{assigning '__global int *__private' to '__local int *__private' changes address space of pointer}}
l = gg; // expected-error {{assigning '__global int *__private *__private' to '__local int *__private' changes address space of pointer}}
l = ll; // expected-error {{assigning '__local int *__private *__private' to '__local int *__private' changes address space of pointer}}
l = gg_f; // expected-error {{assigning '__global float *__private *__private' to '__local int *__private' changes address space of pointer}}
l = gg_f; // expected-error {{casting '__global float *__private *' to type '__local int *' changes address space of pointer}}
ll = g; // expected-error {{assigning '__global int *__private' to '__local int *__private *__private' changes address space of pointer}}
ll = gg; // expected-error {{assigning '__global int *__private *__private' to '__local int *__private *__private' changes address space of nested pointer}}
ll = l; // expected-error {{assigning '__local int *__private' to '__local int *__private *__private' changes address space of pointer}}
ll = gg_f; // expected-error {{assigning '__global float *__private *__private' to '__local int *__private *__private' changes address space of nested pointer}}
ll = gg_f; // expected-warning {{casting '__global float *__private *' to type '__local int *__private *' discards qualifiers in nested pointer types}}
gg_f = g; // expected-error {{assigning '__global int *__private' to '__global float *__private *__private' changes address space of pointer}}
gg_f = gg; // expected-warning {{incompatible pointer types assigning to '__global float *__private *__private' from '__global int *__private *__private'}}
gg_f = l; // expected-error {{assigning '__local int *__private' to '__global float *__private *__private' changes address space of pointer}}
gg_f = ll; // expected-error {{assigning '__local int *__private *__private' to '__global float *__private *__private' changes address space of nested pointer}}
gg_f = gg;
// FIXME: This doesn't seem right. This should be an error, not a warning.
__local int * __global * __private * lll;
lll = gg; // expected-warning {{incompatible pointer types assigning to '__local int *__global *__private *__private' from '__global int *__private *__private'}}
typedef __local int * l_t;
typedef __global int * g_t;
__private l_t * pl;
__private g_t * pg;
gg = pl; // expected-error {{assigning '__private l_t *__private' (aka '__local int *__private *__private') to '__global int *__private *__private' changes address space of nested pointer}}
pl = gg; // expected-error {{assigning '__global int *__private *__private' to '__private l_t *__private' (aka '__local int *__private *__private') changes address space of nested pointer}}
gg = pg;
pg = gg;
pg = pl; // expected-error {{assigning '__private l_t *__private' (aka '__local int *__private *__private') to '__private g_t *__private' (aka '__global int *__private *__private') changes address space of nested pointer}}
pl = pg; // expected-error {{assigning '__private g_t *__private' (aka '__global int *__private *__private') to '__private l_t *__private' (aka '__local int *__private *__private') changes address space of nested pointer}}
ll = gg;
void *vp = ll;
}
#else
void nested {
g = gg; // expected-error {{assigning '__global int *__private *__private' to '__global int *' changes address space of pointer}}
g = l; // expected-error {{assigning '__local int *__private' to '__global int *' changes address space of pointer}}
g = ll; // expected-error {{assigning '__local int *__private *__private' to '__global int *' changes address space of pointer}}
g = gg_f; // expected-error {{assigning '__global float *__private *__private' to '__global int *' changes address space of pointer}}
g = gg_f; // expected-error {{C-style cast from '__global float *__private *' to '__global int *' converts between mismatching address spaces}}
gg = g; // expected-error {{assigning '__global int *__private' to '__global int *__private *' changes address space of pointer}}
gg = l; // expected-error {{assigning '__local int *__private' to '__global int *__private *' changes address space of pointer}}
gg = ll; // expected-error {{assigning '__local int *__private *__private' to '__global int *__private *' changes address space of nested pointer}}
gg = gg_f; // expected-error {{incompatible pointer types assigning to '__global int *__private *' from '__global float *__private *__private'}}
gg = gg_f;
l = g; // expected-error {{assigning '__global int *__private' to '__local int *' changes address space of pointer}}
l = gg; // expected-error {{assigning '__global int *__private *__private' to '__local int *' changes address space of pointer}}
l = ll; // expected-error {{assigning '__local int *__private *__private' to '__local int *' changes address space of pointer}}
l = gg_f; // expected-error {{assigning '__global float *__private *__private' to '__local int *' changes address space of pointer}}
l = gg_f; // expected-error {{C-style cast from '__global float *__private *' to '__local int *' converts between mismatching address spaces}}
ll = g; // expected-error {{assigning '__global int *__private' to '__local int *__private *' changes address space of pointer}}
ll = gg; // expected-error {{assigning '__global int *__private *__private' to '__local int *__private *' changes address space of nested pointer}}
ll = l; // expected-error {{assigning '__local int *__private' to '__local int *__private *' changes address space of pointer}}
ll = gg_f; // expected-error {{assigning '__global float *__private *__private' to '__local int *__private *' changes address space of nested pointer}}
ll = gg; //expected-warning{{C-style cast from '__global int *__private *' to '__local int *__private *' changes address space of nested pointers}}
gg_f = g; // expected-error {{assigning '__global int *__private' to '__global float *__private *' changes address space of pointer}}
gg_f = gg; // expected-error {{incompatible pointer types assigning to '__global float *__private *' from '__global int *__private *__private'}}
gg_f = l; // expected-error {{assigning '__local int *__private' to '__global float *__private *' changes address space of pointer}}
gg_f = ll; // expected-error {{assigning '__local int *__private *__private' to '__global float *__private *' changes address space of nested pointer}}
gg_f = gg;
typedef __local int * l_t;
typedef __global int * g_t;
__private l_t * pl;
__private g_t * pg;
gg = pl; // expected-error {{assigning '__private l_t *__private' (aka '__local int *__private *__private') to '__global int *__private *' changes address space of nested pointer}}
pl = gg; // expected-error {{assigning '__global int *__private *__private' to '__private l_t *' (aka '__local int *__private *') changes address space of nested pointer}}
gg = pg;
pg = gg;
pg = pl; // expected-error {{assigning '__private l_t *__private' (aka '__local int *__private *__private') to '__private g_t *' (aka '__global int *__private *') changes address space of nested pointer}}
pl = pg; // expected-error {{assigning '__private g_t *__private' (aka '__global int *__private *__private') to '__private l_t *' (aka '__local int *__private *') changes address space of nested pointer}}
ll = gg;
void *vp = ll;
}
#endif
__private int func_return_priv; //expected-error {{return value cannot be qualified with address space}}
__global int func_return_global; //expected-error {{return value cannot be qualified with address space}}
__local int func_return_local; //expected-error {{return value cannot be qualified with address space}}
__constant int func_return_constant; //expected-error {{return value cannot be qualified with address space}}
#if __OPENCL_C_VERSION__ >= 200
__generic int func_return_generic; //expected-error {{return value cannot be qualified with address space}}
#endif
void func_multiple_addr {
typedef __private int private_int_t;
__private __local int var1; // expected-error {{multiple address spaces specified for type}}
__private __local int *var2; // expected-error {{multiple address spaces specified for type}}
__local private_int_t var3; // expected-error {{multiple address spaces specified for type}}
__local private_int_t *var4; // expected-error {{multiple address spaces specified for type}}
__private private_int_t var5; // expected-warning {{multiple identical address spaces specified for type}}
__private private_int_t *var6;// expected-warning {{multiple identical address spaces specified for type}}
}
void func_with_array_param;
__kernel void k {
unsigned data[16];
func_with_array_param;
}
void func_multiple_addr2 {
typedef __private int private_int_t;
__attribute__ __private int var1; // expected-error {{multiple address spaces specified for type}} \
// expected-error {{function scope variable cannot be declared in global address space}}
__private __attribute__ int *var2; // expected-error {{multiple address spaces specified for type}}
__attribute__ private_int_t var3; // expected-error {{multiple address spaces specified for type}}
__attribute__ private_int_t *var4; // expected-error {{multiple address spaces specified for type}}
__attribute__ private_int_t var5; // expected-warning {{multiple identical address spaces specified for type}}
__attribute__ private_int_t *var6; // expected-warning {{multiple identical address spaces specified for type}}
#if __OPENCL_CPP_VERSION__
__global int [[clang::opencl_private]] var7; // expected-error {{multiple address spaces specified for type}}
__global int [[clang::opencl_private]] *var8; // expected-error {{multiple address spaces specified for type}}
private_int_t [[clang::opencl_private]] var9; // expected-warning {{multiple identical address spaces specified for type}}
private_int_t [[clang::opencl_private]] *var10; // expected-warning {{multiple identical address spaces specified for type}}
#endif // !__OPENCL_CPP_VERSION__
}