[llvm-branch-commits] [libcxx] 8db33f6 - [libc++] Fix vector::append_range growing before the capacity is reached (#183264)
Douglas Yung via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 5 09:26:47 PST 2026
Author: Nikolas Klauser
Date: 2026-03-05T17:26:34Z
New Revision: 8db33f635a4605d5072c3741fe6e6ac9f9a56bcf
URL: https://github.com/llvm/llvm-project/commit/8db33f635a4605d5072c3741fe6e6ac9f9a56bcf
DIFF: https://github.com/llvm/llvm-project/commit/8db33f635a4605d5072c3741fe6e6ac9f9a56bcf.diff
LOG: [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)
Added:
Modified:
libcxx/include/__vector/vector.h
libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp
Removed:
################################################################################
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);
}
}
More information about the llvm-branch-commits
mailing list