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); Index: libcxx/test/libcxx/containers/sequences/vector.bool/reserve.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/libcxx/containers/sequences/vector.bool/reserve.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// +// vector + +// void reserve(size_type new_cap); + +#include +#include + +#include "test_macros.h" +#include "test_allocator.h" + +int main(int, char**) +{ + typedef std::vector::__storage_type storage_type; + const unsigned bits_per_word + = static_cast(sizeof(storage_type) * CHAR_BIT); + // Maximum capacity in words (units of type storage_type) + const unsigned max_cap_words = 100; + // Maximum capacity in bits + const unsigned max_cap_bits = bits_per_word * max_cap_words; + // Half of the maximum capacity in bits + const unsigned half_cap_bits = max_cap_bits / 2; + + { + std::vector > v; + assert(v.capacity() == 0); + assert(v.size() == 0); + v.reserve(half_cap_bits); + assert(v.capacity() == half_cap_bits); + assert(v.size() == 0); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::vector > v; + v.reserve(half_cap_bits); + assert(v.capacity() == half_cap_bits); + try { + v.reserve(max_cap_bits + 1); + assert(false); + } catch (const std::length_error&) { + // no-op + } + assert(v.capacity() == half_cap_bits); + } +#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; }