[PATCH v5] libstdc++: allocate_at_least ask only what it reports (P0401)

Torbjorn SVENSSON torbjorn.svensson@foss.st.com
Thu Jun 11 12:02:09 GMT 2026


Hi all,

I've opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125741 to cover the regression for arm-none-eabi.

Kind regards,
Torbjörn

On 2026-06-10 18:15, Jonathan Wakely wrote:
> 
> 
> On Wed, 10 Jun 2026, 16:20 Nathan Myers, <ncm@cantrip.org <mailto:ncm@cantrip.org>> wrote:
> 
> 
>     I could see it identifying v with v1, but why does the backing
>     storage (whatever ends up owning it) not need to be deallocated?
>     Who will do it instead?
> 
> 
> There is no backing store. The point of the test is to verify that the unused copy of v is completely optimised away.
> 
> 
> 
>     And why would this vary by target?
> 
>     Nathan Myers
> 
>     On 6/10/26 9:03 AM, Torbjorn SVENSSON wrote:
>      > Hello,
>      >
>      > It looks like this change is introducing a regression for arm-none-eabi:
>      >
>      > Testing tree-ssa/pr109442.C,  -std=gnu++11
>      > doing compile
>      > Executing on host: /build/r17-1372-g80b78b2504fba0/bin/arm-none-eabi-g+
>      > +  /build/gcc_src/gcc/testsuite/g++.dg/tree-ssa/pr109442.C  -mthumb -
>      > march=armv6s-m -mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto   -
>      > fdiagnostics-plain-output   -fmessage-length=0  -std=gnu++11 -O2 -fdump-
>      > tree-optimized  -S     -o pr109442.s    (timeout = 800)
>      > spawn -ignore SIGHUP /build/r17-1372-g80b78b2504fba0/bin/arm-none-eabi-
>      > g++ /build/gcc_src/gcc/testsuite/g++.dg/tree-ssa/pr109442.C -mthumb -
>      > march=armv6s-m -mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto -
>      > fdiagnostics-plain-output -fmessage-length=0 -std=gnu++11 -O2 -fdump-
>      > tree-optimized -S -o pr109442.s
>      > pid is 430895 -430895
>      > pid is -1
>      > output is  status 0
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++11 (test for excess errors)
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++11  scan-tree-dump-not
>      > optimized "_M_start"
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++11  scan-tree-dump-not
>      > optimized "delete"
>      > Testing tree-ssa/pr109442.C,  -std=gnu++23
>      > doing compile
>      > Executing on host: /build/r17-1372-g80b78b2504fba0/bin/arm-none-eabi-g+
>      > +  /build/gcc_src/gcc/testsuite/g++.dg/tree-ssa/pr109442.C  -mthumb -
>      > march=armv6s-m -mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto   -
>      > fdiagnostics-plain-output   -fmessage-length=0  -std=gnu++23 -O2 -fdump-
>      > tree-optimized  -S     -o pr109442.s    (timeout = 800)
>      > spawn -ignore SIGHUP /build/r17-1372-g80b78b2504fba0/bin/arm-none-eabi-
>      > g++ /build/gcc_src/gcc/testsuite/g++.dg/tree-ssa/pr109442.C -mthumb -
>      > march=armv6s-m -mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto -
>      > fdiagnostics-plain-output -fmessage-length=0 -std=gnu++23 -O2 -fdump-
>      > tree-optimized -S -o pr109442.s
>      > pid is 431059 -431059
>      > pid is -1
>      > output is  status 0
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++23 (test for excess errors)
>      > FAIL: g++.dg/tree-ssa/pr109442.C  -std=gnu++23  scan-tree-dump-not
>      > optimized "_M_start"
>      > FAIL: g++.dg/tree-ssa/pr109442.C  -std=gnu++23  scan-tree-dump-not
>      > optimized "delete"
>      > Testing tree-ssa/pr109442.C,  -std=gnu++20
>      > doing compile
>      > Executing on host: /build/r17-1372-g80b78b2504fba0/bin/arm-none-eabi-g+
>      > +  /build/gcc_src/gcc/testsuite/g++.dg/tree-ssa/pr109442.C  -mthumb -
>      > march=armv6s-m -mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto   -
>      > fdiagnostics-plain-output   -fmessage-length=0  -std=gnu++20 -O2 -fdump-
>      > tree-optimized  -S     -o pr109442.s    (timeout = 800)
>      > spawn -ignore SIGHUP /build/r17-1372-g80b78b2504fba0/bin/arm-none-eabi-
>      > g++ /build/gcc_src/gcc/testsuite/g++.dg/tree-ssa/pr109442.C -mthumb -
>      > march=armv6s-m -mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto -
>      > fdiagnostics-plain-output -fmessage-length=0 -std=gnu++20 -O2 -fdump-
>      > tree-optimized -S -o pr109442.s
>      > pid is 431306 -431306
>      > pid is -1
>      > output is  status 0
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++20 (test for excess errors)
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++20  scan-tree-dump-not
>      > optimized "_M_start"
>      > PASS: g++.dg/tree-ssa/pr109442.C  -std=gnu++20  scan-tree-dump-not
>      > optimized "delete"
>      > std_list: 20 98 26
>      >
>      >
>      >
>      >
>      > With -std=gnu+20, it produces code like:
>      >
>      >          .type   _Z4vat1St6vectorIiSaIiEE, %function
>      > _Z4vat1St6vectorIiSaIiEE:
>      >          .fnstart
>      > .LFB1718:
>      >          @ args = 0, pretend = 0, frame = 0
>      >          @ frame_needed = 0, uses_anonymous_args = 0
>      >          @ link register save eliminated.
>      >          movs    r0, #10
>      >          @ sp needed
>      >          bx      lr
>      >          .cantunwind
>      >          .fnend
>      >          .size   _Z4vat1St6vectorIiSaIiEE, .-_Z4vat1St6vectorIiSaIiEE
>      >
>      >
>      > With -std=gnu+23, it instead produces code like:
>      >
>      >          .type   _Z4vat1St6vectorIiSaIiEE, %function
>      > _Z4vat1St6vectorIiSaIiEE:
>      >          .fnstart
>      > .LFB1898:
>      >          @ args = 0, pretend = 0, frame = 0
>      >          @ frame_needed = 0, uses_anonymous_args = 0
>      >          ldmia   r0, {r0, r3}
>      >          subs    r0, r3, r0
>      >          push    {r4, r5, r6, lr}
>      >          .save {r4, r5, r6, lr}
>      >          asrs    r5, r0, #2
>      >          beq     .L2
>      >          movs    r2, #7
>      >          adds    r3, r0, #7
>      >          bics    r3, r2
>      >          asrs    r2, r3, #31
>      >          subs    r3, r3, r0
>      >          adds    r3, r2, r3
>      >          movs    r4, r0
>      >          cmp     r3, #3
>      >          bls     .L10
>      >          adds    r0, r0, #4
>      >          bl      _Znwj
>      >          ldr     r3, .L11
>      >          adds    r5, r5, #1
>      >          cmp     r5, r3
>      >          bls     .L5
>      >          movs    r5, r3
>      > .L5:
>      >          lsls    r4, r5, #2
>      >          movs    r1, r4
>      >          bl      _ZdlPvj
>      > .L2:
>      >          @ sp needed
>      >          movs    r0, #10
>      >          pop     {r4, r5, r6, pc}
>      > .L10:
>      >          bl      _Znwj
>      >          movs    r1, r4
>      >          bl      _ZdlPvj
>      >          b       .L2
>      > .L12:
>      >          .align  2
>      > .L11:
>      >          .word   536870911
>      >          .fnend
>      >          .size   _Z4vat1St6vectorIiSaIiEE, .-_Z4vat1St6vectorIiSaIiEE
>      >
>      >
>      >
>      > Kind regards,
>      > Torbjörn
>      >
>      >
>      > On 2026-05-29 09:04, Jonathan Wakely wrote:
>      >> On Thu, 28 May 2026 at 20:53, Nathan Myers <ncm@cantrip.org <mailto:ncm@cantrip.org>> wrote:
>      >>>
>      >>> Changes in v5:
>      >>>   - Rename __ask -> __bytes in __new_allocator<>::allocate_at_least.
>      >>>   - Guard __new_allocator<>::allocate_at_least body vs.
>      >>> __cpp_aligned_new.
>      >>>   - Make new test pass when __cpp_aligned_new is not defined.
>      >>>   - Make new test pass when __cpp_sized_deallocation is not defined
>      >>>   - Include stdlib.h in test, to get malloc and free.
>      >>>   - Omit unused parameter name in defn of op delete(p, n).
>      >>>
>      >>> Changes in v4:
>      >>>   - Simplify calculation.
>      >>>   - Drop __builtin_unreachable(), as compiler seems unable to use it.
>      >>>   - Distinguish objects of size 8 or more, where __bonus can be only
>      >>>    0 or 1, as compilers do not notice.
>      >>>   - Test more thoroughly.
>      >>>
>      >>> Changes in v3:
>      >>>   - Calculate extra allocations with no attempt to force 8-bit
>      >>>    division, which pessimized everything except x86.
>      >>>   - Add test to verify allocate_at_least change.
>      >>>   - Also fix vector insert_vs_emplace.cc as run built with -m32.
>      >>>
>      >>> (Please ignore v2.)
>      >>>
>      >>> allocate_at_least is rounding up the allocation request size to
>      >>> its default alignment, which may be more than an integral
>      >>> multiple of the object size requested. When the memory is freed,
>      >>> what the container reports it is freeing differs from the amount
>      >>> that was allocated. This patch rounds the request size back down
>      >>> to what will be reported to the caller.
>      >>>
>      >>> The algorithm to compute the allocation is altered in response
>      >>> to findings on godbolt.org <http://godbolt.org>, which indicate dropping to uint8 to
>      >>> perform the division is a pessimization everywhere other than
>      >>> x86. The new version is implemented with multiplication,
>      >>> instead.
>      >>>
>      >>> In addition, the remaining -m32 test that failed under the new
>      >>> allocation method is fixed.
>      >>>
>      >>> Tested on x86 -m64/-m32.
>      >>>
>      >>> libstdc++-v3/ChangeLog:
>      >>>          * include/bits/new_allocator.h (allocate_at_least): Reduce
>      >>>          allocation to match what is reported.
>      >>>          * testsuite/20_util/allocator/allocate_at_least2.cc: Add tests.
>      >>>          * testsuite/23_containers/vector/modifiers/
>      >>> insert_vs_emplace.cc:
>      >>>          Fix for -m32 and new allocation results.
>      >>
>      >> OK, thanks
>      >>
>      >>> ---
>      >>>   libstdc++-v3/include/bits/new_allocator.h     | 30 ++++++---
>      >>>   .../20_util/allocator/allocate_at_least2.cc   | 66 +++++++++++++++++++
>      >>>   .../vector/modifiers/insert_vs_emplace.cc     | 48 +++++++++-----
>      >>>   3 files changed, 116 insertions(+), 28 deletions(-)
>      >>>   create mode 100644 libstdc++-v3/testsuite/20_util/allocator/
>      >>> allocate_at_least2.cc
>      >>>
>      >>> diff --git a/libstdc++-v3/include/bits/new_allocator.h b/libstdc++-
>      >>> v3/include/bits/new_allocator.h
>      >>> index 4524355a4a0..e7666b5831c 100644
>      >>> --- a/libstdc++-v3/include/bits/new_allocator.h
>      >>> +++ b/libstdc++-v3/include/bits/new_allocator.h
>      >>> @@ -177,6 +177,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      >>>         [[nodiscard]] constexpr std::allocation_result<_Tp*, size_t>
>      >>>         allocate_at_least(size_t __n)
>      >>>         {
>      >>> +#if __cpp_aligned_new
>      >>>          if ! consteval
>      >>>            {
>      >>>              if constexpr (requires { sizeof(_Tp); })
>      >>> @@ -184,19 +185,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      >>>              if constexpr ( sizeof(_Tp) <
>      >>> __STDCPP_DEFAULT_NEW_ALIGNMENT__)
>      >>>                {
>      >>>                  _S_check_allocation_limit(__n);
>      >>> -               const size_t __need = __n * sizeof(_Tp);
>      >>> +               size_t __bytes = __n * sizeof(_Tp);
>      >>>                  const size_t __mask =
>      >>> __STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1;
>      >>> -               size_t __ask = (__need + __mask) & ~__mask;
>      >>> -               // Avoid rounding up to and asking for 2^63 bytes
>      >>> (PR108377):
>      >>> -               __ask -= __ask >> (__SIZE_WIDTH__ - 1);
>      >>> -               auto* __p =
>      >>> static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__ask));
>      >>> -               using _U8 = const unsigned char;
>      >>> -               static_assert(sizeof(_Tp) <= ~_U8());
>      >>> -               // Use 8-bit division for minimal latency:
>      >>> -               _U8 __spare = __ask - __need, __size = sizeof(_Tp);
>      >>> -               return { __p , __n + __spare / __size };
>      >>> +               size_t __max = (__bytes + __mask) & ~__mask;
>      >>> +               // Avoid seeming to ask for 2^63 bytes (PR108377):
>      >>> +               __max -= __max >> (__SIZE_WIDTH__ - 1);
>      >>> +               auto __spare = static_cast<unsigned>(__max - __bytes);
>      >>> +               if constexpr (sizeof(_Tp) < (__mask + 1) / 2)
>      >>> +                 {
>      >>> +                   auto __bonus = __spare / sizeof(_Tp);
>      >>> +                   __n += __bonus;
>      >>> +                   __bytes += __bonus * sizeof(_Tp);
>      >>> +                 }
>      >>> +               else if (sizeof(_Tp) <= __spare)
>      >>> +                 {
>      >>> +                   __n += 1;
>      >>> +                   __bytes += sizeof(_Tp);
>      >>> +                 }
>      >>> +               void* __p = _GLIBCXX_OPERATOR_NEW(__bytes);
>      >>> +               return { static_cast<_Tp*>(__p), __n };
>      >>>                }
>      >>>            }
>      >>> +#endif
>      >>>          return { allocate(__n), __n };
>      >>>         }
>      >>>   #endif
>      >>> diff --git a/libstdc++-v3/testsuite/20_util/allocator/
>      >>> allocate_at_least2.cc b/libstdc++-v3/testsuite/20_util/allocator/
>      >>> allocate_at_least2.cc
>      >>> new file mode 100644
>      >>> index 00000000000..4f8645ed50d
>      >>> --- /dev/null
>      >>> +++ b/libstdc++-v3/testsuite/20_util/allocator/allocate_at_least2.cc
>      >>> @@ -0,0 +1,66 @@
>      >>> +// { dg-do run { target c++23 } }
>      >>> +
>      >>> +#include <memory>
>      >>> +#include <stdlib.h>
>      >>> +#include <testsuite_hooks.h>
>      >>> +
>      >>> +std::size_t gn = 0;
>      >>> +void* operator new(std::size_t n)
>      >>> +{
>      >>> +  gn = n;
>      >>> +  return ::malloc(n);
>      >>> +}
>      >>> +
>      >>> +// Failing to define ops delete, too, would generate warnings.
>      >>> +
>      >>> +void operator delete(void* p) noexcept
>      >>> +{ ::free(p); }
>      >>> +
>      >>> +#if __cpp_sized_deallocation
>      >>> +void operator delete(void* p, std::size_t) noexcept
>      >>> +{ ::free(p); }
>      >>> +#endif
>      >>> +
>      >>> +template <unsigned size, unsigned n>
>      >>> +void test_nm()
>      >>> +{
>      >>> +  struct A { char a[size]; };
>      >>> +  std::allocator<A> alloc;
>      >>> +  using alloc_traits = std::allocator_traits<std::allocator<A>>;
>      >>> +  auto [p, m] = alloc_traits::allocate_at_least(alloc, n);
>      >>> +
>      >>> +#if __cpp_aligned_new
>      >>> +  unsigned mod = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
>      >>> +  unsigned max = ((n * size) + mod - 1) & ~(mod - 1);
>      >>> +  unsigned count = max / sizeof(A);
>      >>> +#else
>      >>> +  unsigned count = n;
>      >>> +#endif
>      >>> +  VERIFY(m == count);
>      >>> +  VERIFY(gn == count * sizeof(A));
>      >>> +  VERIFY(p != nullptr);  // named it, use it.
>      >>> +}
>      >>> +
>      >>> +void test()
>      >>> +{                  //  m  gn
>      >>> +  test_nm<1,3>();  // 16  16
>      >>> +  test_nm<2,3>();  //  8  16
>      >>> +  test_nm<3,3>();  //  5  15
>      >>> +  test_nm<4,3>();  //  4  16
>      >>> +  test_nm<5,3>();  //  3  15
>      >>> +  test_nm<6,3>();  //  5  30
>      >>> +  test_nm<7,3>();  //  4  28
>      >>> +  test_nm<8,3>();  //  4  32
>      >>> +  test_nm<9,3>();  //  3  27
>      >>> +  test_nm<10,3>(); //  3  30
>      >>> +  test_nm<11,3>(); //  4  44
>      >>> +  test_nm<12,3>(); //  4  48
>      >>> +  test_nm<13,3>(); //  3  39
>      >>> +  test_nm<14,3>(); //  3  42
>      >>> +  test_nm<15,3>(); //  3  45
>      >>> +}
>      >>> +
>      >>> +int main()
>      >>> +{
>      >>> +  test();
>      >>> +}
>      >>> diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/
>      >>> insert_vs_emplace.cc b/libstdc++-v3/testsuite/23_containers/vector/
>      >>> modifiers/insert_vs_emplace.cc
>      >>> index 187e433d9d3..d226490d6f3 100644
>      >>> --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/
>      >>> insert_vs_emplace.cc
>      >>> +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/
>      >>> insert_vs_emplace.cc
>      >>> @@ -223,11 +223,12 @@ test03()
>      >>>   void
>      >>>   test04()
>      >>>   {
>      >>> -  const X::special expected{ 0, 3, 1, 0, 3, 0 };
>      >>> +  const X::special expected{ 0, 4, 1, 0, 4, 0 };
>      >>>     X::special ins, emp;
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -241,7 +242,8 @@ test04()
>      >>>     }
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -261,11 +263,12 @@ test04()
>      >>>   void
>      >>>   test05()
>      >>>   {
>      >>> -  const X::special expected{ 0, 3, 0, 0, 4, 0 };
>      >>> +  const X::special expected{ 0, 4, 0, 0, 5, 0 };
>      >>>     X::special ins, emp;
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -279,7 +282,8 @@ test05()
>      >>>     }
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -299,11 +303,12 @@ test05()
>      >>>   void
>      >>>   test06()
>      >>>   {
>      >>> -  const X::special expected{ 1, 4, 0, 0, 4, 0 };
>      >>> +  const X::special expected{ 1, 5, 0, 0, 5, 0 };
>      >>>     X::special ins, emp;
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -316,7 +321,8 @@ test06()
>      >>>     }
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -447,11 +453,12 @@ test09()
>      >>>   void
>      >>>   test10()
>      >>>   {
>      >>> -  const X::special expected{ 0, 3, 1, 0, 3, 0 };
>      >>> +  const X::special expected{ 0, 4, 1, 0, 4, 0 };
>      >>>     X::special ins, emp;
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -465,7 +472,8 @@ test10()
>      >>>     }
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -485,11 +493,12 @@ test10()
>      >>>   void
>      >>>   test11()
>      >>>   {
>      >>> -  const X::special expected{ 0, 3, 0, 0, 4, 0 };
>      >>> +  const X::special expected{ 0, 4, 0, 0, 5, 0 };
>      >>>     X::special ins, emp;
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -503,7 +512,8 @@ test11()
>      >>>     }
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -523,11 +533,12 @@ test11()
>      >>>   void
>      >>>   test12()
>      >>>   {
>      >>> -  const X::special expected{ 1, 4, 0, 0, 4, 0 };
>      >>> +  const X::special expected{ 1, 5, 0, 0, 5, 0 };
>      >>>     X::special ins, emp;
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> @@ -540,7 +551,8 @@ test12()
>      >>>     }
>      >>>     {
>      >>>       std::vector<X> v;
>      >>> -    v.reserve(3);
>      >>> +    v.reserve(4);
>      >>> +    v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>>       v.push_back(X(0,0));
>      >>> --
>      >>> 2.54.0
>      >>>
>      >>
>      >
> 



More information about the Libstdc++ mailing list