[PATCH] libstdc++: Small allocator fixes

Jonathan Wakely jwakely.gcc@gmail.com
Mon Apr 13 19:29:59 GMT 2026


On Mon, 13 Apr 2026 at 20:05, Nathan Myers <ncm@cantrip.org> wrote:
>
> Since 2022, the constexpr branch of std::allocator::allocate(n)
> has asked for the wrong size. More recently, allocator_traits
> allocate_at_least has taken its allocator argument by value,
> incorrectly.
>
> libstdc++-v3/ChangeLog:
>         * include/bits/allocator.h (allocate): When constexpr, allocate bytes.
>         * include/bits/alloc_traits.h (allocate_at_least): Take allocator
>         argument by reference, per spec.
> ---
>  libstdc++-v3/include/bits/alloc_traits.h | 2 +-
>  libstdc++-v3/include/bits/allocator.h    | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
> index 2be8ed561d4..e4e0f1608de 100644
> --- a/libstdc++-v3/include/bits/alloc_traits.h
> +++ b/libstdc++-v3/include/bits/alloc_traits.h
> @@ -670,7 +670,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>         *  Returns `a.allocate_at_least(n)`.
>        */
>        [[nodiscard]] static constexpr auto
> -      allocate_at_least(allocator_type __a, size_type __n)
> +      allocate_at_least(allocator_type& __a, size_type __n)

This part is OK.

>         -> allocation_result<pointer, size_type>
>        { return __a.allocate_at_least(__n); }
>  #endif
> diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
> index 9c22c805ebe..ae735605f67 100644
> --- a/libstdc++-v3/include/bits/allocator.h
> +++ b/libstdc++-v3/include/bits/allocator.h
> @@ -200,7 +200,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>           {
>             if (__builtin_mul_overflow(__n, sizeof(_Tp), &__n))

This line performs n * sizeof(T) and stores the result in n (returning
true if it overflows).

So it's equivalent the n *= sizeof(T).

>               std::__throw_bad_array_new_length();
> -           return static_cast<_Tp*>(::operator new(__n));
> +           return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));

So this is wrong.

>           }
>
>         return __allocator_base<_Tp>::allocate(__n, 0);
> --
> 2.53.0
>


More information about the Libstdc++ mailing list