]> granicus.if.org Git - clang/commitdiff
[OpenCL] Added diagnostic for checking length of vector
authorEgor Churaev <egor.churaev@gmail.com>
Tue, 21 Mar 2017 13:20:57 +0000 (13:20 +0000)
committerEgor Churaev <egor.churaev@gmail.com>
Tue, 21 Mar 2017 13:20:57 +0000 (13:20 +0000)
Reviewers: Anastasia, cfe-commits

Reviewed By: Anastasia

Subscribers: bader, yaxunl

Differential Revision: https://reviews.llvm.org/D30937

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@298369 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprMember.cpp
test/SemaOpenCL/vector_swizzle_length.cl [new file with mode: 0644]

index 74dabe7f3fa83a748ebebef7b7eef2f15f1c2635..fe40cb002d08936619aa1173ef95cd3bc9dbbe06 100644 (file)
@@ -8236,6 +8236,8 @@ def err_opencl_ptrptr_kernel_param : Error<
 def err_kernel_arg_address_space : Error<
   "pointer arguments to kernel functions must reside in '__global', "
   "'__constant' or '__local' address space">;
+def err_opencl_ext_vector_component_invalid_length : Error<
+  "vector component access has invalid length %0.  Supported: 1,2,3,4,8,16.">;
 def err_opencl_function_variable : Error<
   "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">;
 def err_static_function_scope : Error<
index f08bdc5e9c814721af548e565cd11fc3289a7ce8..542f10ba2da3a4234faf5c32f6077434c8810dd1 100644 (file)
@@ -284,6 +284,14 @@ IsRGBA(char c) {
   }
 }
 
+// OpenCL v1.1, s6.1.7
+// The component swizzle length must be in accordance with the acceptable
+// vector sizes.
+static bool IsValidOpenCLComponentSwizzleLength(unsigned len)
+{
+  return (len >= 1 && len <= 4) || len == 8 || len == 16;
+}
+
 /// Check an ext-vector component access expression.
 ///
 /// VK should be set in advance to the value kind of the base
@@ -376,6 +384,19 @@ CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK,
     }
   }
 
+  if (!HalvingSwizzle) {
+    unsigned SwizzleLength = CompName->getLength();
+
+    if (HexSwizzle)
+      SwizzleLength--;
+
+    if (IsValidOpenCLComponentSwizzleLength(SwizzleLength) == false) {
+      S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length)
+        << SwizzleLength << SourceRange(CompLoc);
+      return QualType();
+    }
+  }
+
   // The component accessor looks fine - now we need to compute the actual type.
   // The vector type is implied by the component accessor. For example,
   // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
diff --git a/test/SemaOpenCL/vector_swizzle_length.cl b/test/SemaOpenCL/vector_swizzle_length.cl
new file mode 100644 (file)
index 0000000..94e3f65
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+typedef float float8 __attribute__((ext_vector_type(8)));
+
+void foo() {
+    float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0);
+
+    f2.s01234; // expected-error {{vector component access has invalid length 5.  Supported: 1,2,3,4,8,16}}
+    f2.xyzxy; // expected-error {{vector component access has invalid length 5.  Supported: 1,2,3,4,8,16}}
+}