https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/183722
Backport d6fcf47a893475f6f3dbcace29093297b7e9f366 Requested by: @philnik777 >From 73e8810482d74deae73552b4a9e93b254db41126 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser <[email protected]> Date: Fri, 27 Feb 2026 11:12:17 +0100 Subject: [PATCH] [libc++] Fix vector::append_range growing before the capacity is reached (#183264) Currently `vector::append_range` grows even when appending a number of elements that is exactly equal to its spare capacity, which is guaranteed by the standard to _not_ happen. Fixes #183256 (cherry picked from commit d6fcf47a893475f6f3dbcace29093297b7e9f366) --- libcxx/include/__vector/vector.h | 2 +- .../vector/vector.modifiers/append_range.pass.cpp | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 0151f7cf4180e..4e48b1c2016b1 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -487,7 +487,7 @@ class vector { _LIBCPP_HIDE_FROM_ABI constexpr void append_range(_Range&& __range) { if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { auto __len = ranges::distance(__range); - if (__len < __cap_ - __end_) { + if (__len <= __cap_ - __end_) { __construct_at_end(ranges::begin(__range), ranges::end(__range), __len); } else { __split_buffer<value_type, allocator_type> __buffer(__recommend(size() + __len), size(), __alloc_); diff --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp index 3b4bbf642809a..78dd44482b2b1 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp @@ -46,14 +46,25 @@ constexpr bool test() { assert(std::ranges::equal(v, std::array{1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10})); } - { // Ensure no reallocation happens. + { // Ensure no reallocation happens, and that we don't invalidate iterators- int in[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8}; v.reserve(v.size() + std::ranges::size(in)); - assert(v.capacity() >= v.size() + std::ranges::size(in)); + + auto ptr = v.data(); + auto old_cap = v.capacity(); v.append_range(in); + assert(v.capacity() == old_cap); assert(std::ranges::equal(v, std::array{1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10})); + + // vector is allowed to overallocate. Make sure it doesn't reallocate until the new capacity is reached. + while (v.size() < old_cap) { + int in2[] = {0}; + v.append_range(in2); + assert(v.capacity() == old_cap); + } + assert(v.data() == ptr); } } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
