[libcxx-commits] [libcxx] [libc++] Fix vector::append_range growing before the capacity is reached (PR #183264)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 25 01:15:05 PST 2026


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/183264

Currently `vector::append_range` grows already when trying to append to exactly the capacity, which is guaranteed by the standard to _not_ happen.

Fixes #183256


>From 564a65d1b60861386a4e2fa519db6f519c490cf0 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 25 Feb 2026 10:12:54 +0100
Subject: [PATCH] [libc++] Fix vector::append_range growing before the capacity
 is reached

---
 libcxx/include/__vector/vector.h                         | 2 +-
 .../vector/vector.modifiers/append_range.pass.cpp        | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index d1c3f7ddcec1c..181230df819ea 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -483,7 +483,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 {
         _SplitBuffer __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..7f8943db2510c 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
@@ -52,8 +52,17 @@ constexpr bool test() {
       v.reserve(v.size() + std::ranges::size(in));
       assert(v.capacity() >= v.size() + std::ranges::size(in));
 
+      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);
+      }
     }
   }
 



More information about the libcxx-commits mailing list