aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2009-06-26 00:50:28 +0000
committerNate Begeman <natebegeman@mac.com>2009-06-26 00:50:28 +0000
commit58d29a41271d96509f464716f79b0ab2e815b6b1 (patch)
tree9a644d31eb64ebc7bea4f7926d0cf22c825ea257
parent1140186abc9c6bd39f50d9866892e0b050e5f938 (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.td3
-rw-r--r--lib/Sema/Sema.h7
-rw-r--r--lib/Sema/SemaExpr.cpp36
-rw-r--r--test/Sema/ext_vector_casts.c23
-rw-r--r--test/Sema/vector-cast.c4
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 \