1 // RUN: %clang_cc1 -x c++ -std=c++14 -fsyntax-only -verify %s 2 3 template <int I, int J, int K> 4 void car() { 5 int __attribute__((address_space(I))) __attribute__((address_space(J))) * Y; // expected-error {{multiple address spaces specified for type}} 6 int *__attribute__((address_space(I))) __attribute__((address_space(J))) * Z; // expected-error {{multiple address spaces specified for type}} 7 8 __attribute__((address_space(I))) int local; // expected-error {{automatic variable qualified with an address space}} 9 __attribute__((address_space(J))) int array[5]; // expected-error {{automatic variable qualified with an address space}} 10 __attribute__((address_space(I))) int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}} 11 12 __attribute__((address_space(J))) * x; // expected-error {{a type specifier is required for all declarations}} 13 14 __attribute__((address_space(I))) float *B; 15 16 typedef __attribute__((address_space(J))) int AS2Int; 17 struct HasASFields { 18 AS2Int typedef_as_field; // expected-error {{field may not be qualified with an address space}} 19 }; 20 21 struct _st { 22 int x, y; 23 } s __attribute((address_space(I))) = {1, 1}; 24 } 25 26 template <int I> 27 struct HasASTemplateFields { 28 __attribute__((address_space(I))) int as_field; // expected-error {{field may not be qualified with an address space}} 29 }; 30 31 template <int I, int J> 32 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}} 33 __attribute__((address_space(J))) float b) { 34 *a = 5.0f + b; 35 } 36 37 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}} 38 39 template <int I> 40 void neg() { 41 __attribute__((address_space(I))) int *bounds; // expected-error {{address space is negative}} 42 } 43 44 template <long int I> 45 void tooBig() { 46 __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388585)}} 47 } 48 49 template <long int I> 50 void correct() { 51 __attribute__((address_space(I))) int *bounds; 52 } 53 54 template <int I, int J> 55 char *cmp(__attribute__((address_space(I))) char *x, __attribute__((address_space(J))) char *y) { 56 return x < y ? x : y; // expected-error {{comparison of distinct pointer types ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *')}} 57 } 58 59 typedef void ft(void); 60 61 template <int I> 62 struct fooFunction { 63 __attribute__((address_space(I))) void **const base = 0; 64 65 void *get_0(void) { 66 return base[0]; // expected-error {{cannot initialize return object of type 'void *' with an lvalue of type '__attribute__((address_space(1))) void *}} 67 } 68 69 __attribute__((address_space(I))) ft qf; // expected-error {{function type may not be qualified with an address space}} 70 __attribute__((address_space(I))) char *test3_val; 71 72 void test3(void) { 73 extern void test3_helper(char *p); // expected-note {{passing argument to parameter 'p' here}} 74 test3_helper(test3_val); // expected-error {{cannot initialize a parameter of type 'char *' with an lvalue of type '__attribute__((address_space(1))) char *'}} 75 } 76 }; 77 78 template <typename T, int N> 79 int GetAddressSpaceValue(T __attribute__((address_space(N))) * p) { 80 return N; 81 } 82 83 template <unsigned A> int __attribute__((address_space(A))) *same_template(); 84 template <unsigned B> int __attribute__((address_space(B))) *same_template(); 85 void test_same_template() { (void) same_template<0>(); } 86 87 template <unsigned A> int __attribute__((address_space(A))) *different_template(); // expected-note {{candidate function [with A = 0]}} 88 template <unsigned B> int __attribute__((address_space(B+1))) *different_template(); // expected-note {{candidate function [with B = 0]}} 89 void test_different_template() { (void) different_template<0>(); } // expected-error {{call to 'different_template' is ambiguous}} 90 91 template <typename T> struct partial_spec_deduce_as; 92 template <typename T, unsigned AS> 93 struct partial_spec_deduce_as <__attribute__((address_space(AS))) T *> { 94 static const unsigned value = AS; 95 }; 96 97 int main() { 98 int __attribute__((address_space(1))) * p1; 99 int p = GetAddressSpaceValue(p1); 100 101 car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}} 102 HasASTemplateFields<1> HASTF; 103 neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}} 104 correct<0x7FFFE9>(); 105 tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}} 106 107 __attribute__((address_space(1))) char *x; 108 __attribute__((address_space(2))) char *y; 109 cmp<1, 2>(x, y); // expected-note {{in instantiation of function template specialization 'cmp<1, 2>' requested here}} 110 111 fooFunction<1> ff; 112 ff.get_0(); // expected-note {{in instantiation of member function 'fooFunction<1>::get_0' requested here}} 113 ff.qf(); 114 ff.test3(); // expected-note {{in instantiation of member function 'fooFunction<1>::test3' requested here}} 115 116 static_assert(partial_spec_deduce_as<int __attribute__((address_space(3))) *>::value == 3, "address space value has been incorrectly deduced"); 117 118 return 0; 119 } 120 121 namespace gh101685 { 122 template <int AS> 123 using ASPtrTy = void [[clang::address_space(AS)]] *; 124 125 template <int AS> 126 struct EntryTy { 127 ASPtrTy<AS> Base; 128 }; 129 130 ASPtrTy<1> x; 131 EntryTy<2> y; 132 } 133