[libcxx-commits] [libcxx] [libc++] Fix size_t overflow in make_shared<T[]> and allocate_shared<T[]> (PR #223735)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 16 02:45:45 PDT 2026
================
@@ -738,17 +739,28 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count {
// Returns the number of bytes required to store a control block followed by the given number
// of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
+ //
+ // Throws std::bad_array_new_length if that number of bytes is not representable as a size_t.
_LIBCPP_HIDE_FROM_ABI static constexpr size_t __bytes_for(size_t __elements) {
+ constexpr size_t __align = alignof(__unbounded_array_control_block);
+
// When there's 0 elements, the control block alone is enough since it holds one element.
// Otherwise, we allocate one fewer element than requested because the control block already
- // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
- // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
+ // holds one.
+ size_t __bytes = sizeof(__unbounded_array_control_block);
+ if (__elements != 0) {
+ if (__builtin_mul_overflow(__elements - 1, sizeof(_Tp), &__bytes) ||
+ __builtin_add_overflow(__bytes, sizeof(__unbounded_array_control_block), &__bytes))
+ std::__throw_bad_array_new_length();
----------------
philnik777 wrote:
`__builtin_mul_overflow` + `__builtin_add_overflow` seems to be an _incredibly_ common pattern. 3 out of 4 current uses of `__builtin_add_overflow` are that pattern and the last one is `saturating_add`. Should we maybe introduce a `__checked_mul_add(__elements - 1, sizeof(_Tp), sizeof(__unbounded_array_control_block))`?
https://github.com/llvm/llvm-project/pull/223735
More information about the libcxx-commits
mailing list