fhahn updated this revision to Diff 348360. fhahn added a comment. I discussed the problem offline with John and he suggested to handle matrix casts in TryStaticCast. This allows us the handle both static_cast and C-style casts with the same code. As a consequence, the default error messages for casting a matrix type to a non-matrix type and vice versa are used.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D103163/new/ https://reviews.llvm.org/D103163 Files: clang/lib/Sema/SemaCast.cpp clang/test/CodeGenCXX/matrix-casts.cpp clang/test/SemaCXX/matrix-casts.cpp
Index: clang/test/SemaCXX/matrix-casts.cpp =================================================================== --- clang/test/SemaCXX/matrix-casts.cpp +++ clang/test/SemaCXX/matrix-casts.cpp @@ -26,23 +26,16 @@ m2 = m1; // expected-error {{assigning to 'matrix_4_4<int>' from incompatible type 'matrix_4_4<char>'}} m3 = (matrix_4_4<short>)m2; (matrix_5_5<int>)m3; // expected-error {{conversion between matrix types 'matrix_5_5<int>' (aka 'int __attribute__\ -((matrix_type(5, 5)))') and 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, 4)))') of different size is not\ - allowed}} - - (int)m3; // expected-error {{conversion between matrix type 'matrix_4_4<short>' (aka 'short __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'int' is not allowed}} - (matrix_4_4<int>)i; // expected-error {{conversion between matrix type 'matrix_4_4<int>' (aka 'int __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'int' is not allowed}} - - (vec) m2; // expected-error {{conversion between matrix type 'matrix_4_4<int>' (aka 'int __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'vec' (vector of 1 'int' value) is not allowed}} - (matrix_4_4<char>)v; // expected-error {{conversion between matrix type 'matrix_4_4<char>' (aka 'char __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'vec' (vector of 1 'int' value) is not allowed}} - - (test_struct *)m1; // expected-error {{conversion between matrix type 'matrix_4_4<char>' (aka 'char __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'test_struct *' is not allowed}}' - (matrix_5_5<float>)s; // expected-error {{conversion between matrix type 'matrix_5_5<float>' (aka 'float __attribute__\ -((matrix_type(5, 5)))') and incompatible type 'test_struct *' is not allowed}}' +((matrix_type(5, 5)))') and 'short __attribute__((matrix_type(4, 4)))' of different size is not allowed}} + + (int)m3; // expected-error {{C-style cast from 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, 4)))') to 'int' is not allowed}} + (matrix_4_4<int>)i; // expected-error {{C-style cast from 'int' to 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') is not allowed}} + + (vec) m2; // expected-error {{C-style cast from 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') to 'vec' (vector of 1 'int' value) is not allowed}} + (matrix_4_4<char>)v; // expected-error {{C-style cast from 'vec' (vector of 1 'int' value) to 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') is not allowed}} + + (test_struct *)m1; // expected-error {{cannot cast from type 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') to pointer type 'test_struct *'}} + (matrix_5_5<float>)s; // expected-error {{C-style cast from 'test_struct *' to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}} } void f2() { @@ -57,23 +50,16 @@ m2 = static_cast<matrix_4_4<int>>(m1); m3 = static_cast<matrix_4_4<short>>(m2); static_cast<matrix_5_5<int>>(m3); // expected-error {{conversion between matrix types 'matrix_5_5<int>' (aka 'int __attribute__\ -((matrix_type(5, 5)))') and 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, 4)))') of different size is not\ - allowed}} - - static_cast<int>(m3); // expected-error {{conversion between matrix type 'matrix_4_4<short>' (aka 'short __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'int' is not allowed}} - static_cast<matrix_4_4<int>>(i); // expected-error {{conversion between matrix type 'matrix_4_4<int>' (aka 'int __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'int' is not allowed}} - - static_cast<vec>(m2); // expected-error {{conversion between matrix type 'matrix_4_4<int>' (aka 'int __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'vec' (vector of 1 'int' value) is not allowed}} - static_cast<matrix_4_4<char>>(v); // expected-error {{conversion between matrix type 'matrix_4_4<char>' (aka 'char __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'vec' (vector of 1 'int' value) is not allowed}} - - static_cast<test_struct *>(m1); // expected-error {{conversion between matrix type 'matrix_4_4<char>' (aka 'char __attribute__\ -((matrix_type(4, 4)))') and incompatible type 'test_struct *' is not allowed}}' - static_cast<matrix_5_5<float>>(s); // expected-error {{conversion between matrix type 'matrix_5_5<float>' (aka 'float __attribute__\ -((matrix_type(5, 5)))') and incompatible type 'test_struct *' is not allowed}}' +((matrix_type(5, 5)))') and 'short __attribute__((matrix_type(4, 4)))' of different size is not allowed}} + + static_cast<int>(m3); // expected-error {{static_cast from 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, 4)))') to 'int' is not allowed}} + static_cast<matrix_4_4<int>>(i); // expected-error {{static_cast from 'int' to 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') is not allowed}} + + static_cast<vec>(m2); // expected-error {{static_cast from 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') to 'vec' (vector of 1 'int' value) is not allowed}} + static_cast<matrix_4_4<char>>(v); // expected-error {{static_cast from 'vec' (vector of 1 'int' value) to 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') is not allowed}} + + static_cast<test_struct *>(m1); // expected-error {{cannot cast from type 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') to pointer type 'test_struct *'}} + static_cast<matrix_5_5<float>>(s); // expected-error {{static_cast from 'test_struct *' to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}} } void f3() { @@ -87,7 +73,7 @@ m2 = (matrix_4_4<double>)m1; (matrix_5_5<double>)m1; // expected-error {{conversion between matrix types 'matrix_5_5<double>' (aka 'double __\ -attribute__((matrix_type(5, 5)))') and 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') of different\ +attribute__((matrix_type(5, 5)))') and 'float __attribute__((matrix_type(4, 4)))' of different\ size is not allowed}} m4 = (matrix_5_5<signed int>)m3; m5 = (matrix_5_5<unsigned int>)m4; // expected-error {{assigning to 'matrix_4_4<unsigned int>' (aka 'unsigned int \ @@ -108,8 +94,8 @@ m2 = static_cast<matrix_4_4<double>>(m1); static_cast<matrix_5_5<double>>(m1); // expected-error {{conversion between matrix types 'matrix_5_5<double>' (aka 'double __\ -attribute__((matrix_type(5, 5)))') and 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') of different\ - size is not allowed}} +attribute__((matrix_type(5, 5)))') and 'float __attribute__((matrix_type(4, 4)))' of different size is not allowed}} + m4 = static_cast<matrix_5_5<signed int>>(m3); m5 = static_cast<matrix_5_5<unsigned int>>(m4); // expected-error {{assigning to 'matrix_4_4<unsigned int>' (aka 'unsigned int \ __attribute__((matrix_type(4, 4)))') from incompatible type 'matrix_5_5<unsigned int>' (aka 'unsigned int __attribute__\ @@ -117,3 +103,33 @@ m6 = static_cast<matrix_5_5<unsigned int>>(m4); m4 = static_cast<matrix_5_5<signed int>>(m6); } + +class Foo { + // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') to 'const Foo' for 1st argument}} + // expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') to 'Foo' for 1st argument}} + + int x; + +public: + Foo(); + // expected-note@-1 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + Foo(matrix_5_5<int> x); + // expected-note@-1 {{candidate constructor not viable: no known conversion from 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') to 'matrix_5_5<int>' (aka 'int __attribute__((matrix_type(5, 5)))') for 1st argument}} +}; + +struct Bar { + // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'matrix_4_4<unsigned int>' (aka 'unsigned int __attribute__((matrix_type(4, 4)))') to 'const Bar' for 1st argument}} + // expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'matrix_4_4<unsigned int>' (aka 'unsigned int __attribute__((matrix_type(4, 4)))') to 'Bar' for 1st argument}} + // expected-note@-3 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} + float x; +}; + +void f5_constructors() { + matrix_4_4<float> m1; + matrix_4_4<unsigned int> m5; + + Foo F = Foo(m1); + // expected-error@-1 {{no matching conversion for functional-style cast from 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') to 'Foo'}} + Bar B = Bar(m5); + // expected-error@-1 {{no matching conversion for functional-style cast from 'matrix_4_4<unsigned int>' (aka 'unsigned int __attribute__((matrix_type(4, 4)))') to 'Bar'}} +} Index: clang/test/CodeGenCXX/matrix-casts.cpp =================================================================== --- clang/test/CodeGenCXX/matrix-casts.cpp +++ clang/test/CodeGenCXX/matrix-casts.cpp @@ -341,3 +341,33 @@ matrix_5_5<unsigned long int> u; u = static_cast<matrix_5_5<unsigned long int>>(i); } + +class Foo { + int x[10]; + +public: + Foo(matrix_5_5<int> x); +}; + +Foo class_constructor_matrix_ty(matrix_5_5<int> m) { + // CHECK-LABEL: define void @_Z27class_constructor_matrix_tyu11matrix_typeILm5ELm5EiE(%class.Foo* noalias sret(%class.Foo) align 4 %agg.result, <25 x i32> %m) + // CHECK: [[M:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4 + // CHECK-NEXT: call void @_ZN3FooC1Eu11matrix_typeILm5ELm5EiE(%class.Foo* nonnull align 4 dereferenceable(40) %agg.result, <25 x i32> [[M]]) + // CHECK-NEXT: ret void + + return Foo(m); +} + +struct Bar { + float x[10]; + Bar(matrix_4_4<float> x); +}; + +Bar struct_constructor_matrix_ty(matrix_4_4<float> m) { + // CHECK-LABEL: define void @_Z28struct_constructor_matrix_tyu11matrix_typeILm4ELm4EfE(%struct.Bar* noalias sret(%struct.Bar) align 4 %agg.result, <16 x float> %m) + // CHECK: [[M:%.*]] = load <16 x float>, <16 x float>* {{.*}}, align 4 + // CHECK-NEXT: call void @_ZN3BarC1Eu11matrix_typeILm4ELm4EfE(%struct.Bar* nonnull align 4 dereferenceable(40) %agg.result, <16 x float> [[M]]) + // CHECK-NEXT: ret void + + return Bar(m); +} Index: clang/lib/Sema/SemaCast.cpp =================================================================== --- clang/lib/Sema/SemaCast.cpp +++ clang/lib/Sema/SemaCast.cpp @@ -1179,13 +1179,6 @@ return; } - if (DestType->getAs<MatrixType>() || - SrcExpr.get()->getType()->getAs<MatrixType>()) { - if (Self.CheckMatrixCast(OpRange, DestType, SrcExpr.get()->getType(), Kind)) - SrcExpr = ExprError(); - return; - } - // This test is outside everything else because it's the only case where // a non-lvalue-reference target type does not lead to decay. // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". @@ -1452,6 +1445,14 @@ DestPointer->getPointeeType()->getAs<RecordType>()) msg = diag::err_bad_cxx_cast_unrelated_class; + if (SrcType->getAs<MatrixType>() && DestType->getAs<MatrixType>()) { + if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) { + SrcExpr = ExprError(); + return TC_Failed; + } + return TC_Success; + } + // We tried everything. Everything! Nothing works! :-( return TC_NotApplicable; } @@ -2665,13 +2666,6 @@ return; } - if (DestType->getAs<MatrixType>() || - SrcExpr.get()->getType()->getAs<MatrixType>()) { - if (Self.CheckMatrixCast(OpRange, DestType, SrcExpr.get()->getType(), Kind)) - SrcExpr = ExprError(); - return; - } - // AltiVec vector initialization with a single literal. if (const VectorType *vecTy = DestType->getAs<VectorType>()) if (vecTy->getVectorKind() == VectorType::AltiVecVector
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits