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
|
// RUN: %clang_cc1 -x c++ -std=c++14 -fsyntax-only -verify %s
template <int I, int J, int K>
void car() {
int __attribute__((address_space(I))) __attribute__((address_space(J))) * Y; // expected-error {{multiple address spaces specified for type}}
int *__attribute__((address_space(I))) __attribute__((address_space(J))) * Z; // expected-error {{multiple address spaces specified for type}}
__attribute__((address_space(I))) int local; // expected-error {{automatic variable qualified with an address space}}
__attribute__((address_space(J))) int array[5]; // expected-error {{automatic variable qualified with an address space}}
__attribute__((address_space(I))) int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
__attribute__((address_space(J))) * x; // expected-error {{a type specifier is required for all declarations}}
__attribute__((address_space(I))) float *B;
typedef __attribute__((address_space(J))) int AS2Int;
struct HasASFields {
AS2Int typedef_as_field; // expected-error {{field may not be qualified with an address space}}
};
struct _st {
int x, y;
} s __attribute((address_space(I))) = {1, 1};
}
template <int I>
struct HasASTemplateFields {
__attribute__((address_space(I))) int as_field; // expected-error {{field may not be qualified with an address space}}
};
template <int I, int J>
void foo(__attribute__((address_space(I))) float *a, // expected-note {{candidate template ignored: substitution failure [with I = 1, J = 2]: parameter may not be qualified with an address space}}
__attribute__((address_space(J))) float b) {
*a = 5.0f + b;
}
template void foo<1, 2>(float *, float); // expected-error {{explicit instantiation of 'foo' does not refer to a function template, variable template, member function, member class, or static data member}}
template <int I>
void neg() {
__attribute__((address_space(I))) int *bounds; // expected-error {{address space is negative}}
}
template <long int I>
void tooBig() {
__attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388582)}}
}
template <long int I>
void correct() {
__attribute__((address_space(I))) int *bounds;
}
template <int I, int J>
char *cmp(__attribute__((address_space(I))) char *x, __attribute__((address_space(J))) char *y) {
return x < y ? x : y; // expected-error {{comparison of distinct pointer types ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *')}}
}
typedef void ft(void);
template <int I>
struct fooFunction {
__attribute__((address_space(I))) void **const base = 0;
void *get_0(void) {
return base[0]; // expected-error {{cannot initialize return object of type 'void *' with an lvalue of type '__attribute__((address_space(1))) void *}}
}
__attribute__((address_space(I))) ft qf; // expected-error {{function type may not be qualified with an address space}}
__attribute__((address_space(I))) char *test3_val;
void test3(void) {
extern void test3_helper(char *p); // expected-note {{passing argument to parameter 'p' here}}
test3_helper(test3_val); // expected-error {{cannot initialize a parameter of type 'char *' with an lvalue of type '__attribute__((address_space(1))) char *'}}
}
};
template <typename T, int N>
int GetAddressSpaceValue(T __attribute__((address_space(N))) * p) {
return N;
}
template <unsigned A> int __attribute__((address_space(A))) *same_template();
template <unsigned B> int __attribute__((address_space(B))) *same_template();
void test_same_template() { (void) same_template<0>(); }
template <unsigned A> int __attribute__((address_space(A))) *different_template(); // expected-note {{candidate function [with A = 0]}}
template <unsigned B> int __attribute__((address_space(B+1))) *different_template(); // expected-note {{candidate function [with B = 0]}}
void test_different_template() { (void) different_template<0>(); } // expected-error {{call to 'different_template' is ambiguous}}
template <typename T> struct partial_spec_deduce_as;
template <typename T, unsigned AS>
struct partial_spec_deduce_as <__attribute__((address_space(AS))) T *> {
static const unsigned value = AS;
};
int main() {
int __attribute__((address_space(1))) * p1;
int p = GetAddressSpaceValue(p1);
car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}}
HasASTemplateFields<1> HASTF;
neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
correct<0x7FFFE6>();
tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
__attribute__((address_space(1))) char *x;
__attribute__((address_space(2))) char *y;
cmp<1, 2>(x, y); // expected-note {{in instantiation of function template specialization 'cmp<1, 2>' requested here}}
fooFunction<1> ff;
ff.get_0(); // expected-note {{in instantiation of member function 'fooFunction<1>::get_0' requested here}}
ff.qf();
ff.test3(); // expected-note {{in instantiation of member function 'fooFunction<1>::test3' requested here}}
static_assert(partial_spec_deduce_as<int __attribute__((address_space(3))) *>::value == 3, "address space value has been incorrectly deduced");
return 0;
}
namespace gh101685 {
template <int AS>
using ASPtrTy = void [[clang::address_space(AS)]] *;
template <int AS>
struct EntryTy {
ASPtrTy<AS> Base;
};
ASPtrTy<1> x;
EntryTy<2> y;
}
|