diff options
author | Nate Begeman <natebegeman@mac.com> | 2009-06-26 00:50:28 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2009-06-26 00:50:28 +0000 |
commit | 58d29a41271d96509f464716f79b0ab2e815b6b1 (patch) | |
tree | 9a644d31eb64ebc7bea4f7926d0cf22c825ea257 | |
parent | 1140186abc9c6bd39f50d9866892e0b050e5f938 (diff) |
OpenCL 1.0 support: explicit casts to ext-vector types
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74247 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 7 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 36 | ||||
-rw-r--r-- | test/Sema/ext_vector_casts.c | 23 | ||||
-rw-r--r-- | test/Sema/vector-cast.c | 4 |
5 files changed, 69 insertions, 4 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5343cebea7..62e0eb32aa 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1860,6 +1860,9 @@ def err_selector_element_type : Error< def err_collection_expr_type : Error< "collection expression type %0 is not a valid object">; +def err_invalid_conversion_between_ext_vectors : Error< + "invalid conversion between ext-vector type %0 and %1">; + // Type def ext_invalid_sign_spec : Extension<"'%0' cannot be signed or unsigned">; def warn_receiver_forward_class : Warning< diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 36f3ff96f3..48e6772353 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3063,6 +3063,13 @@ public: // returns true if the cast is invalid bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty); + // CheckExtVectorCast - check type constraints for extended vectors. + // Since vectors are an extension, there are no C standard reference for this. + // We allow casting between vectors and integer datatypes of the same size, + // or vectors and the element type of that vector. + // returns true if the cast is invalid + bool CheckExtVectorCast(SourceRange R, QualType VectorTy, QualType Ty); + /// CheckMessageArgumentTypes - Check types in an Obj-C message send. /// \param Method - May be null. /// \param [out] ReturnType - The return type of the send. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a01fbb1e66..3d22321386 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2876,12 +2876,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) { return Diag(castExpr->getLocStart(), diag::err_typecheck_expect_scalar_operand) << castExpr->getType() << castExpr->getSourceRange(); - } else if (castExpr->getType()->isVectorType()) { - if (CheckVectorCast(TyR, castExpr->getType(), castType)) + } else if (castType->isExtVectorType()) { + if (CheckExtVectorCast(TyR, castType, castExpr->getType())) return true; } else if (castType->isVectorType()) { if (CheckVectorCast(TyR, castType, castExpr->getType())) return true; + } else if (castExpr->getType()->isVectorType()) { + if (CheckVectorCast(TyR, castExpr->getType(), castType)) + return true; } else if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr)) { return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR; } else if (!castType->isArithmeticType()) { @@ -2919,6 +2922,35 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) { return false; } +bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) { + assert(DestTy->isExtVectorType() && "Not an extended vector type!"); + + // If SrcTy is also an ExtVectorType, the types must be identical unless + // lax vector conversions is enabled. + if (SrcTy->isExtVectorType()) { + if (getLangOptions().LaxVectorConversions && + Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) + return false; + if (DestTy != SrcTy) + return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) + << DestTy << SrcTy << R; + return false; + } + + // If SrcTy is a VectorType, then only the total size must match. + if (SrcTy->isVectorType()) { + if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)) + return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) + << DestTy << SrcTy << R; + return false; + } + + // All scalar -> ext vector "c-style" casts are legal; the appropriate + // conversion will take place first from scalar to elt type, and then + // splat from elt type to vector. + return false; +} + Action::OwningExprResult Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, SourceLocation RParenLoc, ExprArg Op) { diff --git a/test/Sema/ext_vector_casts.c b/test/Sema/ext_vector_casts.c new file mode 100644 index 0000000000..8aa762ebcf --- /dev/null +++ b/test/Sema/ext_vector_casts.c @@ -0,0 +1,23 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef __attribute__(( ext_vector_type(2) )) float float2; +typedef __attribute__(( ext_vector_type(4) )) int int4; +typedef __attribute__(( ext_vector_type(4) )) float float4; +typedef float t3 __attribute__ ((vector_size (16))); + +static void test() { + float2 vec2; + float4 vec4, vec4_2; + int4 ivec4; + t3 vec4_3; + + vec4 = (float4)5.0f; + vec4 = (float4)5; + vec4 = (float4)vec4_3; + + ivec4 = (int4)5.0f; + ivec4 = (int4)5; + ivec4 = (int4)vec4_3; + + vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}} +} diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c index bd09e69800..9460cac6d1 100644 --- a/test/Sema/vector-cast.c +++ b/test/Sema/vector-cast.c @@ -11,9 +11,9 @@ void f() t3 v3; v2 = (t2)v1; // -expected-error {{invalid conversion between vector type \ -'t1' and 't2' of different size}} - v1 = (t1)v2; // -expected-error {{invalid conversion between vector type \ 't2' and 't1' of different size}} + v1 = (t1)v2; // -expected-error {{invalid conversion between vector type \ +'t1' and 't2' of different size}} v3 = (t3)v2; v1 = (t1)(char *)10; // -expected-error {{invalid conversion between vector \ |