diff --git a/libcxx/include/vector b/libcxx/include/vector index eeca81dfabc1bc..c9b121b3177df2 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -1590,6 +1590,8 @@ vector<_Tp, _Allocator>::reserve(size_type __n) { if (__n > capacity()) { + if (__n > max_size()) + this->__throw_length_error(); allocator_type& __a = this->__alloc(); __split_buffer __v(__n, size(), __a); __swap_out_circular_buffer(__v); @@ -3018,6 +3020,8 @@ vector::reserve(size_type __n) { if (__n > capacity()) { + if (__n > max_size()) + this->__throw_length_error(); vector __v(this->get_allocator()); __v.__vallocate(__n); __v.__construct_at_end(this->begin(), this->end()); diff --git a/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp index c36a779bdc1408..e1f2344bdff155 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp @@ -16,6 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" +#include "test_allocator.h" int main(int, char**) { @@ -56,6 +57,23 @@ int main(int, char**) assert(v.capacity() >= 150); } #endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::vector > v; + v.reserve(5); + try { + // A typical implementation would allocate chunks of bits. + // In libc++ the chunk has the same size as the machine word. It is + // reasonable to assume that in practice no implementation would use + // 64 kB or larger chunks. + v.reserve(10 * 65536); + assert(false); + } catch (const std::length_error&) { + // no-op + } + assert(v.capacity() >= 5); + } +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp index 78cfcc3422cb99..378a67c96ce557 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -67,6 +67,22 @@ int main(int, char**) assert(is_contiguous_container_asan_correct(v)); } #endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::vector > v; + v.reserve(50); + assert(v.capacity() == 50); + assert(is_contiguous_container_asan_correct(v)); + try { + v.reserve(101); + assert(false); + } catch (const std::length_error&) { + // no-op + } + assert(v.capacity() == 50); + assert(is_contiguous_container_asan_correct(v)); + } +#endif return 0; }