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 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
|
// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DCONSTANT -cl-std=CL2.0
// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGLOBAL -cl-std=CL2.0
// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGENERIC -cl-std=CL2.0
/* OpenCLC v2.0 adds a set of restrictions for conversions between pointers to
* different address spaces, mainly described in Sections 6.5.5 and 6.5.6.
*
* It adds notion of overlapping address spaces. The main differention is that
* an unnamed address space is added, called '__generic'. Pointers to the
* generic address space can be interchangabley used with pointers to any
* other address space except for __constant address space (Section 6.5.5).
*
* Based on this there are 3 sets of tests: __generic, named (__global in this
* case), and __constant, that should cover all program paths for CL address
* space conversions used in initialisations, assignments, casts, comparisons
* and arithmetic operations.
*/
#ifdef GENERIC
#define AS generic
#define AS_COMP local
#define AS_INCOMP constant
#endif
#ifdef GLOBAL
#define AS global
#define AS_COMP global
#define AS_INCOMP local
#endif
#ifdef CONSTANT
#define AS constant
#define AS_COMP constant
#define AS_INCOMP global
#endif
void f_glob(global int *arg_glob) {}
#ifndef GLOBAL
// expected-note@-2{{passing argument to parameter 'arg_glob' here}}
#endif
void f_loc(local int *arg_loc) {
} // expected-note@-1{{passing argument to parameter 'arg_loc' here}}
void f_const(constant int *arg_const) {}
#ifndef CONSTANT
// expected-note@-2{{passing argument to parameter 'arg_const' here}}
#endif
void f_priv(private int *arg_priv) {
} // expected-note@-1{{passing argument to parameter 'arg_priv' here}}
void f_gen(generic int *arg_gen) {}
#ifdef CONSTANT
// expected-note@-2{{passing argument to parameter 'arg_gen' here}}
#endif
void test_conversion(global int *arg_glob, local int *arg_loc,
constant int *arg_const, private int *arg_priv,
generic int *arg_gen) {
AS int *var_init1 = arg_glob;
#ifdef CONSTANT
// expected-error@-2{{initializing '__constant int *' with an expression of type '__global int *' changes address space of pointer}}
#endif
AS int *var_init2 = arg_loc;
#ifndef GENERIC
// expected-error-re@-2{{initializing '__{{global|constant}} int *' with an expression of type '__local int *' changes address space of pointer}}
#endif
AS int *var_init3 = arg_const;
#ifndef CONSTANT
// expected-error-re@-2{{initializing '__{{global|generic}} int *' with an expression of type '__constant int *' changes address space of pointer}}
#endif
AS int *var_init4 = arg_priv;
#ifndef GENERIC
// expected-error-re@-2{{initializing '__{{global|constant}} int *' with an expression of type 'int *' changes address space of pointer}}
#endif
AS int *var_init5 = arg_gen;
#ifndef GENERIC
// expected-error-re@-2{{initializing '__{{global|constant}} int *' with an expression of type '__generic int *' changes address space of pointer}}
#endif
AS int *var_cast1 = (AS int *)arg_glob;
#ifdef CONSTANT
// expected-error@-2{{casting '__global int *' to type '__constant int *' changes address space of pointer}}
#endif
AS int *var_cast2 = (AS int *)arg_loc;
#ifndef GENERIC
// expected-error-re@-2{{casting '__local int *' to type '__{{global|constant}} int *' changes address space of pointer}}
#endif
AS int *var_cast3 = (AS int *)arg_const;
#ifndef CONSTANT
// expected-error-re@-2{{casting '__constant int *' to type '__{{global|generic}} int *' changes address space of pointer}}
#endif
AS int *var_cast4 = (AS int *)arg_priv;
#ifndef GENERIC
// expected-error-re@-2{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}}
#endif
AS int *var_cast5 = (AS int *)arg_gen;
#ifdef CONSTANT
// expected-error@-2{{casting '__generic int *' to type '__constant int *' changes address space of pointer}}
#endif
AS int *var_impl;
var_impl = arg_glob;
#ifdef CONSTANT
// expected-error@-2{{assigning '__global int *' to '__constant int *' changes address space of pointer}}
#endif
var_impl = arg_loc;
#ifndef GENERIC
// expected-error-re@-2{{assigning '__local int *' to '__{{global|constant}} int *' changes address space of pointer}}
#endif
var_impl = arg_const;
#ifndef CONSTANT
// expected-error-re@-2{{assigning '__constant int *' to '__{{global|generic}} int *' changes address space of pointer}}
#endif
var_impl = arg_priv;
#ifndef GENERIC
// expected-error-re@-2{{assigning 'int *' to '__{{global|constant}} int *' changes address space of pointer}}
#endif
var_impl = arg_gen;
#ifndef GENERIC
// expected-error-re@-2{{assigning '__generic int *' to '__{{global|constant}} int *' changes address space of pointer}}
#endif
var_cast1 = (AS int *)arg_glob;
#ifdef CONSTANT
// expected-error@-2{{casting '__global int *' to type '__constant int *' changes address space of pointer}}
#endif
var_cast2 = (AS int *)arg_loc;
#ifndef GENERIC
// expected-error-re@-2{{casting '__local int *' to type '__{{global|constant}} int *' changes address space of pointer}}
#endif
var_cast3 = (AS int *)arg_const;
#ifndef CONSTANT
// expected-error-re@-2{{casting '__constant int *' to type '__{{global|generic}} int *' changes address space of pointer}}
#endif
var_cast4 = (AS int *)arg_priv;
#ifndef GENERIC
// expected-error-re@-2{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}}
#endif
var_cast5 = (AS int *)arg_gen;
#ifdef CONSTANT
// expected-error@-2{{casting '__generic int *' to type '__constant int *' changes address space of pointer}}
#endif
AS int *var_cmp;
int b = var_cmp != arg_glob;
#ifdef CONSTANT
// expected-error@-2{{comparison between ('__constant int *' and '__global int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_cmp != arg_loc;
#ifndef GENERIC
// expected-error-re@-2{{comparison between ('__{{global|constant}} int *' and '__local int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_cmp == arg_const;
#ifndef CONSTANT
// expected-error-re@-2{{comparison between ('__{{global|generic}} int *' and '__constant int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_cmp <= arg_priv;
#ifndef GENERIC
// expected-error-re@-2{{comparison between ('__{{global|constant}} int *' and 'int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_cmp >= arg_gen;
#ifdef CONSTANT
// expected-error@-2{{comparison between ('__constant int *' and '__generic int *') which are pointers to non-overlapping address spaces}}
#endif
AS int *var_sub;
b = var_sub - arg_glob;
#ifdef CONSTANT
// expected-error@-2{{arithmetic operation with operands of type ('__constant int *' and '__global int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_sub - arg_loc;
#ifndef GENERIC
// expected-error-re@-2{{arithmetic operation with operands of type ('__{{global|constant}} int *' and '__local int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_sub - arg_const;
#ifndef CONSTANT
// expected-error-re@-2{{arithmetic operation with operands of type ('__{{global|generic}} int *' and '__constant int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_sub - arg_priv;
#ifndef GENERIC
// expected-error-re@-2{{arithmetic operation with operands of type ('__{{global|constant}} int *' and 'int *') which are pointers to non-overlapping address spaces}}
#endif
b = var_sub - arg_gen;
#ifdef CONSTANT
// expected-error@-2{{arithmetic operation with operands of type ('__constant int *' and '__generic int *') which are pointers to non-overlapping address spaces}}
#endif
f_glob(var_sub);
#ifndef GLOBAL
// expected-error-re@-2{{passing '__{{constant|generic}} int *' to parameter of type '__global int *' changes address space of pointer}}
#endif
f_loc(var_sub); // expected-error-re{{passing '__{{global|constant|generic}} int *' to parameter of type '__local int *' changes address space of pointer}}
f_const(var_sub);
#ifndef CONSTANT
// expected-error-re@-2{{passing '__{{global|generic}} int *' to parameter of type '__constant int *' changes address space of pointer}}
#endif
f_priv(var_sub); // expected-error-re{{passing '__{{global|constant|generic}} int *' to parameter of type 'int *' changes address space of pointer}}
f_gen(var_sub);
#ifdef CONSTANT
// expected-error@-2{{passing '__constant int *' to parameter of type '__generic int *' changes address space of pointer}}
#endif
}
void test_ternary() {
AS int *var_cond;
generic int *var_gen;
global int *var_glob;
var_gen = 0 ? var_cond : var_glob;
#ifdef CONSTANT
// expected-error@-2{{conditional operator with the second and third operands of type ('__constant int *' and '__global int *') which are pointers to non-overlapping address spaces}}
#endif
local int *var_loc;
var_gen = 0 ? var_cond : var_loc;
#ifndef GENERIC
// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and '__local int *') which are pointers to non-overlapping address spaces}}
#endif
constant int *var_const;
var_cond = 0 ? var_cond : var_const;
#ifndef CONSTANT
// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|generic}} int *' and '__constant int *') which are pointers to non-overlapping address spaces}}
#endif
private int *var_priv;
var_gen = 0 ? var_cond : var_priv;
#ifndef GENERIC
// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and 'int *') which are pointers to non-overlapping address spaces}}
#endif
var_gen = 0 ? var_cond : var_gen;
#ifdef CONSTANT
// expected-error@-2{{conditional operator with the second and third operands of type ('__constant int *' and '__generic int *') which are pointers to non-overlapping address spaces}}
#endif
void *var_void_gen;
global char *var_glob_ch;
var_void_gen = 0 ? var_cond : var_glob_ch;
#ifdef CONSTANT
// expected-error@-2{{conditional operator with the second and third operands of type ('__constant int *' and '__global char *') which are pointers to non-overlapping address spaces}}
#else
// expected-warning-re@-4{{pointer type mismatch ('__{{global|generic}} int *' and '__global char *')}}
#endif
local char *var_loc_ch;
var_void_gen = 0 ? var_cond : var_loc_ch;
#ifndef GENERIC
// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and '__local char *') which are pointers to non-overlapping address spaces}}
#else
// expected-warning@-4{{pointer type mismatch ('__generic int *' and '__local char *')}}
#endif
constant void *var_void_const;
constant char *var_const_ch;
var_void_const = 0 ? var_cond : var_const_ch;
#ifndef CONSTANT
// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|generic}} int *' and '__constant char *') which are pointers to non-overlapping address spaces}}
#else
// expected-warning@-4{{pointer type mismatch ('__constant int *' and '__constant char *')}}
#endif
private char *var_priv_ch;
var_void_gen = 0 ? var_cond : var_priv_ch;
#ifndef GENERIC
// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and 'char *') which are pointers to non-overlapping address spaces}}
#else
// expected-warning@-4{{pointer type mismatch ('__generic int *' and 'char *')}}
#endif
generic char *var_gen_ch;
var_void_gen = 0 ? var_cond : var_gen_ch;
#ifdef CONSTANT
// expected-error@-2{{conditional operator with the second and third operands of type ('__constant int *' and '__generic char *') which are pointers to non-overlapping address spaces}}
#else
// expected-warning-re@-4{{pointer type mismatch ('__{{global|generic}} int *' and '__generic char *')}}
#endif
}
void test_pointer_chains() {
AS int *AS *var_as_as_int;
AS int *AS_COMP *var_asc_as_int;
AS_INCOMP int *AS_COMP *var_asc_asn_int;
AS_COMP int *AS_COMP *var_asc_asc_int;
// Case 1:
// * address spaces of corresponded most outer pointees overlaps, their canonical types are equal
// * CVR, address spaces and canonical types of the rest of pointees are equivalent.
var_as_as_int = 0 ? var_as_as_int : var_asc_as_int;
// Case 2: Corresponded inner pointees has non-overlapping address spaces.
var_as_as_int = 0 ? var_as_as_int : var_asc_asn_int;
// expected-warning-re@-1{{pointer type mismatch ('__{{(generic|global|constant)}} int *__{{(generic|global|constant)}} *' and '__{{(local|global|constant)}} int *__{{(constant|local|global)}} *')}}
// Case 3: Corresponded inner pointees has overlapping but not equivalent address spaces.
#ifdef GENERIC
var_as_as_int = 0 ? var_as_as_int : var_asc_asc_int;
// expected-warning-re@-1{{pointer type mismatch ('__{{(generic|global|constant)}} int *__{{(generic|global|constant)}} *' and '__{{(local|global|constant)}} int *__{{(local|global|constant)}} *')}}
#endif
}
|