| // RUN: %clang_cc1 %s -fenable-matrix -pedantic -std=c++11 -verify -triple=x86_64-apple-darwin9 |
| |
| typedef float sx5x10_t __attribute__((matrix_type(5, 10))); |
| |
| template <typename EltTy, unsigned Rows, unsigned Columns> |
| struct MyMatrix { |
| using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns))); |
| |
| matrix_t value; |
| }; |
| |
| template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2> |
| typename MyMatrix<EltTy2, R2, C2>::matrix_t add(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) { |
| char *v1 = A.value + B.value; |
| // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}} |
| // expected-error@-3 {{invalid operands to binary expression ('MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}} |
| |
| return A.value + B.value; |
| // expected-error@-1 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}} |
| } |
| |
| void test_add_template(unsigned *Ptr1, float *Ptr2) { |
| MyMatrix<unsigned, 2, 2> Mat1; |
| MyMatrix<unsigned, 3, 3> Mat2; |
| MyMatrix<float, 2, 2> Mat3; |
| Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1); |
| unsigned v1 = add<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1); |
| // 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)))')}} |
| // expected-note@-2 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}} |
| |
| Mat1.value = add<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2); |
| // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}} |
| |
| Mat1.value = add<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3); |
| // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}} |
| } |
| |
| template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2> |
| typename MyMatrix<EltTy2, R2, C2>::matrix_t subtract(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) { |
| char *v1 = A.value - B.value; |
| // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))')}} |
| // expected-error@-3 {{invalid operands to binary expression ('MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))')}} |
| |
| return A.value - B.value; |
| // expected-error@-1 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') and 'MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))')}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))')}} |
| } |
| |
| void test_subtract_template(unsigned *Ptr1, float *Ptr2) { |
| MyMatrix<unsigned, 2, 2> Mat1; |
| MyMatrix<unsigned, 3, 3> Mat2; |
| MyMatrix<float, 2, 2> Mat3; |
| Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1); |
| unsigned v1 = subtract<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1); |
| // 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)))')}} |
| // expected-note@-2 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}} |
| |
| Mat1.value = subtract<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2); |
| // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}} |
| |
| Mat1.value = subtract<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3); |
| // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}} |
| } |
| |
| template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2> |
| typename MyMatrix<EltTy2, R2, C2>::matrix_t multiply(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) { |
| char *v1 = A.value * B.value; |
| // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}} |
| // expected-error@-3 {{invalid operands to binary expression ('MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}} |
| |
| MyMatrix<int, 5, 6> m; |
| B.value = m.value * A.value; |
| // expected-error@-1 {{invalid operands to binary expression ('MyMatrix<int, 5, 6>::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<int, 5, 6>::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix<unsigned int, 3, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))'))}} |
| // expected-error@-3 {{invalid operands to binary expression ('MyMatrix<int, 5, 6>::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}} |
| |
| return A.value * B.value; |
| // expected-error@-1 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix<unsigned int, 3, 3>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<float, 2, 2>::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'MyMatrix<unsigned int, 2, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}} |
| } |
| |
| void test_multiply_template(unsigned *Ptr1, float *Ptr2) { |
| MyMatrix<unsigned, 2, 2> Mat1; |
| MyMatrix<unsigned, 3, 3> Mat2; |
| MyMatrix<float, 2, 2> Mat3; |
| Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1); |
| unsigned v1 = multiply<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1); |
| // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}} |
| // 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)))')}} |
| |
| MyMatrix<unsigned, 3, 2> Mat4; |
| Mat1.value = multiply<unsigned, 3, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat4, Mat2); |
| // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 3U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}} |
| |
| Mat1.value = multiply<float, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat3, Mat1); |
| // expected-note@-1 {{in instantiation of function template specialization 'multiply<float, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}} |
| |
| Mat4.value = Mat4.value * Mat1; |
| // expected-error@-1 {{no viable conversion from 'MyMatrix<unsigned int, 2, 2>' to 'unsigned int'}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<unsigned int, 3, 2>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix<unsigned int, 2, 2>')}} |
| } |
| |
| struct UserT {}; |
| |
| struct StructWithC { |
| operator UserT() { |
| // expected-note@-1 4 {{candidate function}} |
| return {}; |
| } |
| }; |
| |
| void test_DoubleWrapper(MyMatrix<double, 10, 9> &m, StructWithC &c) { |
| m.value = m.value + c; |
| // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<double, 10, 9>::matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))') and 'StructWithC')}} |
| |
| m.value = c + m.value; |
| // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}} |
| // expected-error@-2 {{invalid operands to binary expression ('StructWithC' and 'MyMatrix<double, 10, 9>::matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))'))}} |
| |
| m.value = m.value - c; |
| // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}} |
| // expected-error@-2 {{invalid operands to binary expression ('MyMatrix<double, 10, 9>::matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))') and 'StructWithC')}} |
| |
| m.value = c - m.value; |
| // expected-error@-1 {{no viable conversion from 'StructWithC' to 'double'}} |
| // expected-error@-2 {{invalid operands to binary expression ('StructWithC' and 'MyMatrix<double, 10, 9>::matrix_t' (aka 'double __attribute__((matrix_type(10, 9)))'))}} |
| } |
| |
| sx5x10_t get_matrix(); |
| |
| void insert(sx5x10_t a, float f) { |
| // Non integer indexes. |
| a[3][f] = 0; |
| // expected-error@-1 {{matrix column index is not an integer}} |
| a[f][9] = 0; |
| // expected-error@-1 {{matrix row index is not an integer}} |
| a[f][f] = 0; |
| // expected-error@-1 {{matrix row index is not an integer}} |
| // expected-error@-2 {{matrix column index is not an integer}} |
| a[0][f] = 0; |
| // expected-error@-1 {{matrix column index is not an integer}} |
| |
| // Invalid element type. |
| a[3][4] = &f; |
| // expected-error@-1 {{assigning to 'float' from incompatible type 'float *'; remove &}} |
| |
| // Indexes outside allowed dimensions. |
| a[-1][3] = 10.0; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| a[3][-1] = 10.0; |
| // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}} |
| a[3][-1u] = 10.0; |
| // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}} |
| a[-1u][3] = 10.0; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| a[5][2] = 10.0; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| a[4][10] = 10.0; |
| // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}} |
| a[5][10.0] = f; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| // expected-error@-2 {{matrix column index is not an integer}} |
| |
| get_matrix()[0][0] = f; |
| // expected-error@-1 {{expression is not assignable}} |
| get_matrix()[5][10.0] = f; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| // expected-error@-2 {{matrix column index is not an integer}} |
| get_matrix()[3] = 5.0; |
| // expected-error@-1 {{single subscript expressions are not allowed for matrix values}} |
| |
| float &x = reinterpret_cast<float &>(a[3][3]); |
| // expected-error@-1 {{reinterpret_cast of a matrix element to 'float &' needs its address, which is not allowed}} |
| |
| a[4, 5] = 5.0; |
| // expected-error@-1 {{comma expressions are not allowed as indices in matrix subscript expressions}} |
| // expected-warning@-2 {{left operand of comma operator has no effect}} |
| |
| a[4, 5, 4] = 5.0; |
| // expected-error@-1 {{comma expressions are not allowed as indices in matrix subscript expressions}} |
| // expected-warning@-2 {{left operand of comma operator has no effect}} |
| // expected-warning@-3 {{left operand of comma operator has no effect}} |
| } |
| |
| void extract(sx5x10_t a, float f) { |
| // Non integer indexes. |
| float v1 = a[3][f]; |
| // expected-error@-1 {{matrix column index is not an integer}} |
| float v2 = a[f][9]; |
| // expected-error@-1 {{matrix row index is not an integer}} |
| float v3 = a[f][f]; |
| // expected-error@-1 {{matrix row index is not an integer}} |
| // expected-error@-2 {{matrix column index is not an integer}} |
| |
| // Invalid element type. |
| char *v4 = a[3][4]; |
| // expected-error@-1 {{cannot initialize a variable of type 'char *' with an lvalue of type 'float'}} |
| |
| // Indexes outside allowed dimensions. |
| float v5 = a[-1][3]; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| float v6 = a[3][-1]; |
| // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}} |
| float v8 = a[-1u][3]; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| float v9 = a[5][2]; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| float v10 = a[4][10]; |
| // expected-error@-1 {{matrix column index is outside the allowed range [0, 10)}} |
| float v11 = a[5][10.0]; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| // expected-error@-2 {{matrix column index is not an integer}} |
| |
| float v12 = get_matrix()[0][0]; |
| float v13 = get_matrix()[5][10.0]; |
| // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}} |
| // expected-error@-2 {{matrix column index is not an integer}} |
| } |
| |
| const float &const_subscript_reference(sx5x10_t m) { |
| return m[2][2]; |
| // expected-warning@-1 {{returning reference to local temporary object}} |
| } |
| |
| const float &const_subscript_reference(const sx5x10_t &m) { |
| return m[2][2]; |
| // expected-warning@-1 {{returning reference to local temporary object}} |
| } |
| |
| float &nonconst_subscript_reference(sx5x10_t m) { |
| return m[2][2]; |
| // expected-error@-1 {{non-const reference cannot bind to matrix element}} |
| } |
| |
| void incomplete_matrix_index_expr(sx5x10_t a, float f) { |
| float x = a[3]; |
| // expected-error@-1 {{single subscript expressions are not allowed for matrix values}} |
| a[2] = f; |
| // expected-error@-1 {{single subscript expressions are not allowed for matrix values}} |
| } |