On Mon, 22 Jun 2026, 23:56 Nathan Myers, <[email protected]> wrote:

> GCC 16.1's explicit specialization of std::allocator_traits on
> std::pmr::polymorphic_allocator<T> lacks the required
> definition of allocate_at_least. This patch provides it, and
> tests for its presence in C++23 and up.
>

OK for gcc-16



> libstdc++-v3/Changelog:
>         PR libstdc++/125890
>         * include/bits/memory_resource.h (allocate_at_least): Add to
>         allocator_traits<pmr::polymorphic_allocator> specialization.
>         * testsuite/20_util/polymorphic_allocator/at_least.cc: New test.
> ---
>  libstdc++-v3/include/bits/memory_resource.h   | 17 +++++++++++++
>  .../20_util/polymorphic_allocator/at_least.cc | 25 +++++++++++++++++++
>  2 files changed, 42 insertions(+)
>  create mode 100644
> libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
>
> diff --git a/libstdc++-v3/include/bits/memory_resource.h
> b/libstdc++-v3/include/bits/memory_resource.h
> index e5c6697b07e..a9db58b76a3 100644
> --- a/libstdc++-v3/include/bits/memory_resource.h
> +++ b/libstdc++-v3/include/bits/memory_resource.h
> @@ -48,6 +48,7 @@
>  # include <bits/utility.h>             // index_sequence
>  # include <tuple>                      // tuple, forward_as_tuple
>  #endif
> +#include <bits/memoryfwd.h>
>
>  namespace std _GLIBCXX_VISIBILITY(default)
>  {
> @@ -468,6 +469,22 @@ namespace pmr
>        allocate(allocator_type& __a, size_type __n, const_void_pointer)
>        { return __a.allocate(__n); }
>
> +#ifdef __glibcxx_allocate_at_least
> +      /**
> +       *  @brief  Allocate memory.
> +       *  @param  __a  An allocator.
> +       *  @param  __n  The number of objects to allocate space for.
> +       *  @return Memory of suitable size and alignment for `n` objects
> +       *          of type `value_type`.
> +       *
> +       *  Just returns `{ a.allocate(n), n }`: `polymorphic_allocator`
> +       *  cannot be extended without breaking ABI.
> +      */
> +      [[nodiscard]] static std::allocation_result<pointer, size_type>
> +      allocate_at_least(allocator_type& __a, size_type __n)
> +      { return { __a.allocate(__n), __n }; }
> +#endif
> +
>        /**
>         *  @brief  Deallocate memory.
>         *  @param  __a  An allocator.
> diff --git
> a/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
> b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
> new file mode 100644
> index 00000000000..2910807d030
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc
> @@ -0,0 +1,25 @@
> +// { dg-do run { target c++23 } }
> +
> +#include <memory_resource>
> +#include <testsuite_hooks.h>
> +#include <testsuite_allocator.h>
> +
> +void
> +alloc_at_least()
> +{
> +  struct A { char a; };
> +  using alloc_A = std::pmr::polymorphic_allocator<A>;
> +  using traits_A = std::allocator_traits<alloc_A>;
> +  alloc_A alloc_a;
> +  // This just forwards to alloc_a::allocate:
> +  std::allocation_result result = traits_A::allocate_at_least(alloc_a, 1);
> +  VERIFY(result.count == 1);
> +  VERIFY(result.ptr != nullptr);
> +  auto [pointer, count] = result;
> +  traits_A::deallocate(alloc_a, pointer, count);
> +}
> +
> +int main()
> +{
> +  alloc_at_least();
> +}
> --
> 2.54.0
>
>

Reply via email to