diff options
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 36 | ||||
| -rw-r--r-- | clang/test/Sema/ext_vector_casts.c | 23 | ||||
| -rw-r--r-- | clang/test/Sema/vector-cast.c | 4 | 
5 files changed, 69 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5343cebea76..62e0eb32aad 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 36f3ff96f3b..48e67723539 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a01fbb1e66b..3d223213865 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/test/Sema/ext_vector_casts.c b/clang/test/Sema/ext_vector_casts.c new file mode 100644 index 00000000000..8aa762ebcf2 --- /dev/null +++ b/clang/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/clang/test/Sema/vector-cast.c b/clang/test/Sema/vector-cast.c index bd09e69800c..9460cac6d18 100644 --- a/clang/test/Sema/vector-cast.c +++ b/clang/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 \  | 

