Improve handling of vector casts in C++.

llvm-svn: 82072
This commit is contained in:
Anders Carlsson 2009-09-16 19:19:43 +00:00
parent e8d0150398
commit 570af5d426
3 changed files with 75 additions and 0 deletions

View File

@ -1518,6 +1518,15 @@ def ext_cast_fn_obj : Extension<
"cast between pointer-to-function and pointer-to-object is an extension">;
def err_bad_reinterpret_cast_small_int : Error<
"cast from pointer to smaller type %2 loses information">;
def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
"%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
"to scalar %2 of different size">;
def err_bad_cxx_cast_scalar_to_vector_different_size : Error<
"%select{||reinterpret_cast||C-style cast|}0 from scalar %1 "
"to vector %2 of different size">;
def err_bad_cxx_cast_vector_to_vector_different_size : Error<
"%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
"to vector %2 of different size">;
def err_bad_lvalue_to_rvalue_cast : Error<
"cannot cast from lvalue of type %1 to rvalue reference type %2; types are "
"not compatible">;

View File

@ -956,6 +956,32 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
return TC_Success;
}
bool destIsVector = DestType->isVectorType();
bool srcIsVector = SrcType->isVectorType();
if (srcIsVector || destIsVector) {
bool srcIsScalar = SrcType->isIntegralType() && !SrcType->isEnumeralType();
bool destIsScalar =
DestType->isIntegralType() && !DestType->isEnumeralType();
// Check if this is a cast between a vector and something else.
if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) &&
!(srcIsVector && destIsVector))
return TC_NotApplicable;
// If both types have the same size, we can successfully cast.
if (Self.Context.getTypeSize(SrcType) == Self.Context.getTypeSize(DestType))
return TC_Success;
if (destIsScalar)
msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
else if (srcIsScalar)
msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
else
msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
return TC_Failed;
}
bool destIsPtr = DestType->isPointerType();
bool srcIsPtr = SrcType->isPointerType();
if (!destIsPtr && !srcIsPtr) {

View File

@ -0,0 +1,40 @@
// RUN: clang-cc -fsyntax-only -verify %s
typedef int __v2si __attribute__((__vector_size__(8)));
typedef short __v4hi __attribute__((__vector_size__(8)));
typedef short __v8hi __attribute__((__vector_size__(16)));
struct S { };
void f() {
__v2si v2si;
__v4hi v4hi;
__v8hi v8hi;
unsigned long long ll;
unsigned char c;
S s;
(void)reinterpret_cast<__v2si>(v4hi);
(void)(__v2si)v4hi;
(void)reinterpret_cast<__v4hi>(v2si);
(void)(__v4hi)v2si;
(void)reinterpret_cast<unsigned long long>(v2si);
(void)(unsigned long long)v2si;
(void)reinterpret_cast<__v2si>(ll);
(void)(__v2si)(ll);
(void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'struct S' is not allowed}}
(void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'struct S' is not allowed}}
(void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'struct S' to '__v2si' is not allowed}}
(void)(__v2si)s; // expected-error {{C-style cast from 'struct S' to '__v2si' is not allowed}}
(void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}}
(void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}}
(void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' of different size}}
(void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' to vector '__v8hi' of different size}}
(void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' to vector '__v8hi' of different size}}
(void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' to vector '__v4hi' of different size}}
(void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}}
}