diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1650,11 +1650,8 @@ /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. unsigned VecKind : 3; - /// The number of elements in the vector. - unsigned NumElements : 29 - NumTypeBits; - - enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; + uint32_t NumElements; }; class AttributedTypeBitfields { @@ -3249,10 +3246,6 @@ QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } - static bool isVectorSizeTooLarge(unsigned NumElements) { - return NumElements > VectorTypeBitfields::MaxNumElements; - } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2436,28 +2436,34 @@ return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc, VectorType::GenericVector); - unsigned VectorSize = static_cast(VecSize.getZExtValue() * 8); + // vecSize is specified in bytes - convert to bits. + if (!VecSize.isIntN(61)) { + // Bit size will overflow uint64. + Diag(AttrLoc, diag::err_attribute_size_too_large) + << SizeExpr->getSourceRange(); + return QualType(); + } + uint64_t VectorSizeBits = VecSize.getZExtValue() * 8; unsigned TypeSize = static_cast(Context.getTypeSize(CurType)); - if (VectorSize == 0) { + if (VectorSizeBits == 0) { Diag(AttrLoc, diag::err_attribute_zero_size) << SizeExpr->getSourceRange(); return QualType(); } - // vecSize is specified in bytes - convert to bits. - if (VectorSize % TypeSize) { + if (VectorSizeBits % TypeSize) { Diag(AttrLoc, diag::err_attribute_invalid_size) << SizeExpr->getSourceRange(); return QualType(); } - if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) { + if (VectorSizeBits / TypeSize > std::numeric_limits::max()) { Diag(AttrLoc, diag::err_attribute_size_too_large) << SizeExpr->getSourceRange(); return QualType(); } - return Context.getVectorType(CurType, VectorSize / TypeSize, + return Context.getVectorType(CurType, VectorSizeBits / TypeSize, VectorType::GenericVector); } @@ -2489,6 +2495,11 @@ return QualType(); } + if (!vecSize.isIntN(32)) { + Diag(AttrLoc, diag::err_attribute_size_too_large) + << ArraySize->getSourceRange(); + return QualType(); + } // Unlike gcc's vector_size attribute, the size is specified as the // number of elements, not the number of bytes. unsigned vectorSize = static_cast(vecSize.getZExtValue()); @@ -2499,12 +2510,6 @@ return QualType(); } - if (VectorType::isVectorSizeTooLarge(vectorSize)) { - Diag(AttrLoc, diag::err_attribute_size_too_large) - << ArraySize->getSourceRange(); - return QualType(); - } - return Context.getExtVectorType(T, vectorSize); } diff --git a/clang/test/Sema/types.c b/clang/test/Sema/types.c --- a/clang/test/Sema/types.c +++ b/clang/test/Sema/types.c @@ -69,9 +69,15 @@ char c = (char __attribute__((may_alias))) i; } -// vector size too large -int __attribute__ ((vector_size(8192))) x1; // expected-error {{vector size too large}} -typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vector size too large}} +// vector size +int __attribute__((vector_size(123456))) v1; +int __attribute__((vector_size(0x1000000000))) v2; // expected-error {{vector size too large}} +int __attribute__((vector_size((__int128_t)1 << 100))) v3; // expected-error {{vector size too large}} +int __attribute__((vector_size(0))) v4; // expected-error {{zero vector size}} +typedef int __attribute__((ext_vector_type(123456))) e1; +typedef int __attribute__((ext_vector_type(0x100000000))) e2; // expected-error {{vector size too large}} +typedef int __attribute__((vector_size((__int128_t)1 << 100))) e3; // expected-error {{vector size too large}} +typedef int __attribute__((ext_vector_type(0))) e4; // expected-error {{zero vector size}} // no support for vector enum type enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}} diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp --- a/clang/test/SemaCXX/vector.cpp +++ b/clang/test/SemaCXX/vector.cpp @@ -335,7 +335,7 @@ typedef bool bad __attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}} namespace Templates { -template +template struct TemplateVectorType { typedef Elt __attribute__((__vector_size__(Size))) type; // #1 }; @@ -343,7 +343,7 @@ template struct PR15730 { typedef T __attribute__((vector_size(N * sizeof(T)))) type; - typedef T __attribute__((vector_size(8192))) type2; // #2 + typedef T __attribute__((vector_size(0x1000000000))) type2; // #2 typedef T __attribute__((vector_size(3))) type3; // #3 }; @@ -352,19 +352,20 @@ const TemplateVectorType::type Works2 = {}; // expected-error@#1 {{invalid vector element type 'bool'}} // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type NoBool; + const TemplateVectorType::type NoBool = {}; // expected-error@#1 {{invalid vector element type 'int __attribute__((ext_vector_type(4)))' (vector of 4 'int' values)}} // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type NoComplex; + const TemplateVectorType::type NoComplex = {}; // expected-error@#1 {{vector size not an integral multiple of component size}} // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type BadSize; + const TemplateVectorType::type BadSize = {}; + const TemplateVectorType::type Large = {}; // expected-error@#1 {{vector size too large}} - // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type TooLarge; + // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type TooLarge = {}; // expected-error@#1 {{zero vector size}} // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type Zero; + const TemplateVectorType::type Zero = {}; // expected-error@#2 {{vector size too large}} // expected-error@#3 {{vector size not an integral multiple of component size}}