https://github.com/akash-manna-sky created https://github.com/llvm/llvm-project/pull/226375
Fixes #165458 A `bool` vector declared with `ext_vector_type` isn't lowered as an LLVM vector in memory: `ConvertTypeForMem` packs it into a single integer with one bit per element. `BuildExtVectorType` only checked that the element count fits in 32 bits, though, so a vector of 187,553,262 bools got through Sema and the first consumer that needed its memory type (the zero initializer of a tentative definition here) asked `IntegerType::get` for far more than the 2^23 bits it supports. Loads, stores, constant initializers and debug info would have tripped over the same type. The element count is now bounded by `llvm::IntegerType::MAX_INT_BITS` (2^23 elements) when the type is built, reusing the existing "vector size too large" error, so the type never exists. The bound applies to every element type rather than just `bool`, because Sema also manufactures bool vectors out of other ext vectors: `c ? true : false` with a `char` ext vector condition produces a bool vector of the same length, in C and C++ alike, and crashed the same way. `vector_size` is left alone since it doesn't allow `bool` elements in the first place. >From 66d76058d4bd336d703008de78ba6db42ba8c927 Mon Sep 17 00:00:00 2001 From: Akash Manna <[email protected]> Date: Fri, 25 Sep 2026 11:47:58 +0530 Subject: [PATCH] [Clang] Bound ext_vector_type element count by the widest LLVM integer A bool vector declared with ext_vector_type is not lowered as an LLVM vector in memory: ConvertTypeForMem packs it into a single integer with one bit per element. BuildExtVectorType only checked that the element count fits in 32 bits, so a vector of 187,553,262 bools got through Sema and the first consumer that needed its memory type asked IntegerType::get for far more than the 2^23 bits it supports. The element count is now bounded by llvm::IntegerType::MAX_INT_BITS when the type is built, reusing the existing "vector size too large" error. The bound applies to every element type, because Sema also forms bool vectors from other ext vectors (e.g. `c ? true : false` with a char ext vector condition) and those crashed the same way. Fixes #165458 --- clang/docs/ReleaseNotes.md | 4 ++++ clang/lib/Sema/SemaType.cpp | 8 +++++--- clang/test/Sema/types.c | 9 +++++++++ clang/test/SemaCXX/vector.cpp | 9 +++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index f4a34a37aff52e..d16fada7796ec6 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -567,6 +567,10 @@ features cannot lower the translation-unit ABI level; - Fixed crash (assertion) when the `alloc_align` attribute was applied to a declaration whose type has a `FunctionProtoType` but which is not itself a `FunctionDecl`, such as a function-pointer variable. (#GH122058) +- Fixed a crash on `bool` vectors declared with `ext_vector_type` and more than + 2^23 elements; the attribute now rejects more than 2^23 elements for any + element type. (#GH165458) + - The `counted_by`/`counted_by_or_null` diagnostic that rejects a pointer whose pointee is a struct with a flexible array member (e.g. ``struct with_fam * __sized_by(size) ptr;``) was incorrectly also applied to diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 483f9ab0887991..268d8f145f4ebf 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2483,13 +2483,15 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *SizeExpr, return QualType(); } - if (!VecSize->isIntN(32)) { + // Unlike gcc's vector_size attribute, the size is specified as the + // number of elements, not the number of bytes. Bool vectors are stored as + // an integer with one bit per element and can be formed from any ext + // vector (e.g. by the conditional operator), hence the bound. + if (VecSize->ugt(llvm::IntegerType::MAX_INT_BITS)) { Diag(AttrLoc, diag::err_attribute_size_too_large) << SizeExpr->getSourceRange() << "vector"; 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<unsigned>(VecSize->getZExtValue()); if (VectorSize == 0) { diff --git a/clang/test/Sema/types.c b/clang/test/Sema/types.c index 2be0e6544f3d7b..15e5d30a56594f 100644 --- a/clang/test/Sema/types.c +++ b/clang/test/Sema/types.c @@ -75,6 +75,15 @@ typedef int __attribute__((ext_vector_type(0x100000000))) e2; // expected-e 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}} +// GH165458: at most 2^23 elements, the widest integer type LLVM supports. +typedef _Bool bool512 __attribute__((ext_vector_type(187553262))); // expected-error {{vector size too large}} +bool512 gh165458; +typedef _Bool __attribute__((ext_vector_type(8388609))) e5; // expected-error {{vector size too large}} +typedef int __attribute__((ext_vector_type(8388609))) e6; // expected-error {{vector size too large}} +typedef _Bool __attribute__((ext_vector_type(8388608))) e7; +typedef int __attribute__((ext_vector_type(8388608))) e8; +typedef _Bool __attribute__((ext_vector_type(4096))) e9; + // 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 index 355d93a2b8ceed..87dfa3760541d8 100644 --- a/clang/test/SemaCXX/vector.cpp +++ b/clang/test/SemaCXX/vector.cpp @@ -378,6 +378,15 @@ void Init() { const PR15730<8, char>::type2 PR15730_2 = {}; } +template <unsigned long long N> +struct GH165458 { + typedef bool __attribute__((ext_vector_type(N))) type; // #GH165458 +}; +// expected-error@#GH165458 {{vector size too large}} +// expected-note@+1 {{in instantiation of template class 'Templates::GH165458<187553262>' requested here}} +typedef GH165458<187553262>::type GH165458_TooLarge; +typedef GH165458<8388608>::type GH165458_Max; + } // namespace Templates typedef int inte2 __attribute__((__ext_vector_type__(2))); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
