133 lines · cpp
1// RUN: %clang_cc1 -x c++ -std=c++14 -fsyntax-only -verify %s2 3template <int I, int J, int K>4void 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 26template <int I>27struct HasASTemplateFields {28 __attribute__((address_space(I))) int as_field; // expected-error {{field may not be qualified with an address space}}29};30 31template <int I, int J>32void 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 37template 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 39template <int I>40void neg() {41 __attribute__((address_space(I))) int *bounds; // expected-error {{address space is negative}}42}43 44template <long int I>45void tooBig() {46 __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388582)}}47}48 49template <long int I>50void correct() {51 __attribute__((address_space(I))) int *bounds;52}53 54template <int I, int J>55char *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 59typedef void ft(void);60 61template <int I>62struct 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 78template <typename T, int N>79int GetAddressSpaceValue(T __attribute__((address_space(N))) * p) {80 return N;81}82 83template <unsigned A> int __attribute__((address_space(A))) *same_template();84template <unsigned B> int __attribute__((address_space(B))) *same_template();85void test_same_template() { (void) same_template<0>(); }86 87template <unsigned A> int __attribute__((address_space(A))) *different_template(); // expected-note {{candidate function [with A = 0]}}88template <unsigned B> int __attribute__((address_space(B+1))) *different_template(); // expected-note {{candidate function [with B = 0]}}89void test_different_template() { (void) different_template<0>(); } // expected-error {{call to 'different_template' is ambiguous}}90 91template <typename T> struct partial_spec_deduce_as;92template <typename T, unsigned AS>93struct partial_spec_deduce_as <__attribute__((address_space(AS))) T *> {94 static const unsigned value = AS;95};96 97int 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<0x7FFFE6>();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 121namespace gh101685 {122template <int AS>123using ASPtrTy = void [[clang::address_space(AS)]] *;124 125template <int AS>126struct EntryTy {127 ASPtrTy<AS> Base;128};129 130ASPtrTy<1> x;131EntryTy<2> y;132}133