[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / SemaCXX / matrix-type-operators.cpp
blobc81b9b92628724bdd8125568a6976ea1915b7b7e
1 // RUN: %clang_cc1 %s -fenable-matrix -pedantic -std=c++11 -verify -triple=x86_64-apple-darwin9
3 typedef float sx5x10_t __attribute__((matrix_type(5, 10)));
5 template <typename EltTy, unsigned Rows, unsigned Columns>
6 struct MyMatrix {
7 using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
9 matrix_t value;
12 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
13 typename MyMatrix<EltTy2, R2, C2>::matrix_t add(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) {
14 char *v1 = A.value + B.value;
15 // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
16 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
17 // expected-error@-3 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
19 return A.value + B.value;
20 // expected-error@-1 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
21 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
24 void test_add_template(unsigned *Ptr1, float *Ptr2) {
25 MyMatrix<unsigned, 2, 2> Mat1;
26 MyMatrix<unsigned, 3, 3> Mat2;
27 MyMatrix<float, 2, 2> Mat3;
28 Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
29 unsigned v1 = add<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
30 // expected-error@-1 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
31 // expected-note@-2 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
33 Mat1.value = add<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2);
34 // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
36 Mat1.value = add<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3);
37 // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
40 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
41 typename MyMatrix<EltTy2, R2, C2>::matrix_t subtract(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) {
42 char *v1 = A.value - B.value;
43 // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
44 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))')}}
45 // expected-error@-3 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))')}}
47 return A.value - B.value;
48 // expected-error@-1 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))')}}
49 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))')}}
52 void test_subtract_template(unsigned *Ptr1, float *Ptr2) {
53 MyMatrix<unsigned, 2, 2> Mat1;
54 MyMatrix<unsigned, 3, 3> Mat2;
55 MyMatrix<float, 2, 2> Mat3;
56 Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
57 unsigned v1 = subtract<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
58 // expected-error@-1 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
59 // expected-note@-2 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
61 Mat1.value = subtract<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2);
62 // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
64 Mat1.value = subtract<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3);
65 // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
68 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
69 typename MyMatrix<EltTy2, R2, C2>::matrix_t multiply(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) {
70 char *v1 = A.value * B.value;
71 // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
72 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
73 // expected-error@-3 {{invalid operands to binary expression ('matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
75 MyMatrix<int, 5, 6> m;
76 B.value = m.value * A.value;
77 // expected-error@-1 {{invalid operands to binary expression ('matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
78 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))'))}}
79 // expected-error@-3 {{invalid operands to binary expression ('matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
81 return A.value * B.value;
82 // expected-error@-1 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
83 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
86 void test_multiply_template(unsigned *Ptr1, float *Ptr2) {
87 MyMatrix<unsigned, 2, 2> Mat1;
88 MyMatrix<unsigned, 3, 3> Mat2;
89 MyMatrix<float, 2, 2> Mat3;
90 Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
91 unsigned v1 = multiply<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
92 // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
93 // expected-error@-2 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
95 MyMatrix<unsigned, 3, 2> Mat4;
96 Mat1.value = multiply<unsigned, 3, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat4, Mat2);
97 // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 3U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
99 Mat1.value = multiply<float, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat3, Mat1);
100 // expected-note@-1 {{in instantiation of function template specialization 'multiply<float, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
102 Mat4.value = Mat4.value * Mat1;
103 // expected-error@-1 {{no viable conversion from 'MyMatrix<unsigned int, 2, 2>' to 'unsigned int'}}
104 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix<unsigned int, 2, 2>')}}
107 struct UserT {};
109 struct StructWithC {
110 operator UserT() {
111 // expected-note@-1 4 {{candidate function}}
112 return {};
116 void test_DoubleWrapper(MyMatrix<double, 10, 9> &m, StructWithC &c) {
117 m.value = m.value + c;
118 // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}}
119 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))') and 'StructWithC')}}
121 m.value = c + m.value;
122 // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}}
123 // expected-error@-2 {{invalid operands to binary expression ('StructWithC' and 'matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))'))}}
125 m.value = m.value - c;
126 // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}}
127 // expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))') and 'StructWithC')}}
129 m.value = c - m.value;
130 // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}}
131 // expected-error@-2 {{invalid operands to binary expression ('StructWithC' and 'matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))'))}}
134 sx5x10_t get_matrix();
136 void insert(sx5x10_t a, float f) {
137 // Non integer indexes.
138 a[3][f] = 0;
139 // expected-error@-1 {{matrix column index is not an integer}}
140 a[f][9] = 0;
141 // expected-error@-1 {{matrix row index is not an integer}}
142 a[f][f] = 0;
143 // expected-error@-1 {{matrix row index is not an integer}}
144 // expected-error@-2 {{matrix column index is not an integer}}
145 a[0][f] = 0;
146 // expected-error@-1 {{matrix column index is not an integer}}
148 // Invalid element type.
149 a[3][4] = &f;
150 // expected-error@-1 {{assigning to 'float' from incompatible type 'float *'; remove &}}
152 // Indexes outside allowed dimensions.
153 a[-1][3] = 10.0;
154 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
155 a[3][-1] = 10.0;
156 // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}}
157 a[3][-1u] = 10.0;
158 // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}}
159 a[-1u][3] = 10.0;
160 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
161 a[5][2] = 10.0;
162 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
163 a[4][10] = 10.0;
164 // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}}
165 a[5][10.0] = f;
166 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
167 // expected-error@-2 {{matrix column index is not an integer}}
169 get_matrix()[0][0] = f;
170 // expected-error@-1 {{expression is not assignable}}
171 get_matrix()[5][10.0] = f;
172 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
173 // expected-error@-2 {{matrix column index is not an integer}}
174 get_matrix()[3] = 5.0;
175 // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
177 float &x = reinterpret_cast<float &>(a[3][3]);
178 // expected-error@-1 {{reinterpret_cast of a matrix element to 'float &' needs its address, which is not allowed}}
180 a[4, 5] = 5.0;
181 // expected-error@-1 {{comma expressions are not allowed as indices in matrix subscript expressions}}
182 // expected-warning@-2 {{left operand of comma operator has no effect}}
184 a[4, 5, 4] = 5.0;
185 // expected-error@-1 {{comma expressions are not allowed as indices in matrix subscript expressions}}
186 // expected-warning@-2 {{left operand of comma operator has no effect}}
187 // expected-warning@-3 {{left operand of comma operator has no effect}}
190 void extract(sx5x10_t a, float f) {
191 // Non integer indexes.
192 float v1 = a[3][f];
193 // expected-error@-1 {{matrix column index is not an integer}}
194 float v2 = a[f][9];
195 // expected-error@-1 {{matrix row index is not an integer}}
196 float v3 = a[f][f];
197 // expected-error@-1 {{matrix row index is not an integer}}
198 // expected-error@-2 {{matrix column index is not an integer}}
200 // Invalid element type.
201 char *v4 = a[3][4];
202 // expected-error@-1 {{cannot initialize a variable of type 'char *' with an lvalue of type 'float'}}
204 // Indexes outside allowed dimensions.
205 float v5 = a[-1][3];
206 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
207 float v6 = a[3][-1];
208 // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}}
209 float v8 = a[-1u][3];
210 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
211 float v9 = a[5][2];
212 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
213 float v10 = a[4][10];
214 // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}}
215 float v11 = a[5][10.0];
216 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
217 // expected-error@-2 {{matrix column index is not an integer}}
219 float v12 = get_matrix()[0][0];
220 float v13 = get_matrix()[5][10.0];
221 // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
222 // expected-error@-2 {{matrix column index is not an integer}}
225 const float &const_subscript_reference(sx5x10_t m) {
226 return m[2][2];
227 // expected-warning@-1 {{returning reference to local temporary object}}
230 const float &const_subscript_reference(const sx5x10_t &m) {
231 return m[2][2];
232 // expected-warning@-1 {{returning reference to local temporary object}}
235 float &nonconst_subscript_reference(sx5x10_t m) {
236 return m[2][2];
237 // expected-error@-1 {{non-const reference cannot bind to matrix element}}
240 void incomplete_matrix_index_expr(sx5x10_t a, float f) {
241 float x = a[3];
242 // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
243 a[2] = f;
244 // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}