Index: libcxx/include/vector =================================================================== --- libcxx/include/vector +++ libcxx/include/vector @@ -1590,6 +1590,8 @@ { 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 @@ { 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()); Index: libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector.bool/reserve.pass.cpp +++ 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 @@ 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 + // resonable 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; } Index: libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp =================================================================== --- libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -67,6 +67,22 @@ 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; }