Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8219,6 +8219,8 @@ 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: lib/Sema/SemaExprMember.cpp =================================================================== --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -284,6 +284,16 @@ } } +// OpenCL spec (Section 6.1.7 Vector Components): +// The component group notation can occur on the left hand side of an expression. To form an lvalue, +// swizzling must be applied to an l-value of vector type, contain no duplicate components, +// and it results in an l-value of scalar or vector type, depending on number of components +// specified. Each component must be a supported scalar or vector type. +static bool IsValidSwizzleLength(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 +386,20 @@ } } + if (S.getLangOpts().OpenCL && !HalvingSwizzle) { + compStr = CompName->getNameStart(); + + if (HexSwizzle) + compStr++; + + unsigned swizzleLength = StringRef(compStr).size(); + if (IsValidSwizzleLength(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. Index: test/SemaOpenCL/vector_swizzle_length.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/vector_swizzle_length.cl @@ -0,0 +1,9 @@ +// 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}} +}