https://gcc.gnu.org/g:b99c6da50262bb8e2f45c7e8f4b9d15ad29eb7d8
commit r16-9156-gb99c6da50262bb8e2f45c7e8f4b9d15ad29eb7d8 Author: Nathan Myers <[email protected]> Date: Mon Jun 22 18:36:12 2026 -0400 libstdc++: allocator traits on pmr gets allocate_at_least (P0401) [PR125890] 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. (Partly cherry-picked from r17-603-gacfdad706.) 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. Reviewed-by: Jonathan Wakely <[email protected]> Diff: --- libstdc++-v3/include/bits/memory_resource.h | 17 +++++++++++++++ .../20_util/polymorphic_allocator/at_least.cc | 24 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/libstdc++-v3/include/bits/memory_resource.h b/libstdc++-v3/include/bits/memory_resource.h index e5c6697b07e3..a9db58b76a34 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 000000000000..4384645dde5a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/at_least.cc @@ -0,0 +1,24 @@ +// { dg-do run { target c++23 } } + +#include <memory_resource> +#include <testsuite_hooks.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(); +}
