forked from OSchip/llvm-project
[Matrix] Move C++ matrix cast checks to TryStaticCast.
At the moment, the matrix support in CheckCXXCStyleCast (added in D101696) breaks function-style constructor calls that take a single matrix value, because it is treated as matrix cast. Instead, unify the C++ matrix cast handling by moving the logic to TryStaticCast and only handle the case where both types are matrix types. Otherwise, fall back to the generic mis-match detection. Suggested by @rjmccall Reviewed By: SaurabhJha Differential Revision: https://reviews.llvm.org/D103163
This commit is contained in:
parent
49b2f8328f
commit
5bccdde070
|
@ -1179,13 +1179,6 @@ void CastOperation::CheckStaticCast() {
|
|||
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 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
|
|||
DestPointer->getPointeeType()->getAs<RecordType>())
|
||||
msg = diag::err_bad_cxx_cast_unrelated_class;
|
||||
|
||||
if (SrcType->isMatrixType() && DestType->isMatrixType()) {
|
||||
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 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
|
|||
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
|
||||
|
|
|
@ -341,3 +341,33 @@ void CastIntToUnsignedLongIntStaticCast() {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -26,23 +26,16 @@ void f1() {
|
|||
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}}
|
||||
((matrix_type(5, 5)))') and '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}}
|
||||
(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 {{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}}
|
||||
(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 {{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}}'
|
||||
(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 @@ void f2() {
|
|||
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}}
|
||||
((matrix_type(5, 5)))') and '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<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 {{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<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 {{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}}'
|
||||
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 @@ void f3() {
|
|||
|
||||
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 @@ void f4() {
|
|||
|
||||
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 @@ __attribute__((matrix_type(4, 4)))') from incompatible type 'matrix_5_5<unsigned
|
|||
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'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue