Skip to content

Commit 657b2a3

Browse files
committed
Validate exception throwing for vector mutators on max_size violation
1 parent 2e39533 commit 657b2a3

10 files changed

+307
-10
lines changed

libcxx/test/std/containers/sequences/vector/vector.capacity/reserve_exceptions.pass.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
// UNSUPPORTED: no-exceptions
1010

11+
// <vector>
12+
13+
// void reserve(size_type n);
14+
1115
// This test file validates that std::vector<T>::reserve provides the strong exception guarantee if T is
1216
// Cpp17MoveInsertable and no exception is thrown by the move constructor of T during the reserve call.
1317
// It also checks that if T's move constructor is not noexcept, reserve provides only the basic exception
@@ -36,7 +40,8 @@ void test_allocation_exception_for_strong_guarantee(
3640
std::size_t old_cap = v.capacity();
3741

3842
try {
39-
v.reserve(new_cap);
43+
v.reserve(new_cap); // Expected exception
44+
assert(false);
4045
} catch (...) { // std::length_error, std::bad_alloc
4146
assert(v.data() == old_data);
4247
assert(v.size() == old_size);
@@ -61,7 +66,8 @@ void test_copy_ctor_exception_for_strong_guarantee(std::vector<throwing_data<T>,
6166
std::size_t new_cap = 2 * old_cap;
6267

6368
try {
64-
v.reserve(new_cap);
69+
v.reserve(new_cap); // Expected exception
70+
assert(false);
6571
} catch (...) {
6672
assert(v.data() == old_data);
6773
assert(v.size() == old_size);
@@ -83,7 +89,8 @@ void test_move_ctor_exception_for_basic_guarantee(std::vector<move_only_throwing
8389
v.emplace_back(values[i], throw_after);
8490

8591
try {
86-
v.reserve(2 * v.capacity());
92+
v.reserve(2 * v.capacity()); // Expected exception
93+
assert(false);
8794
} catch (...) {
8895
use_unspecified_but_valid_state_vector(v);
8996
}

libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_exceptions.pass.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
// UNSUPPORTED: no-exceptions
1010

11+
// <vector>
12+
13+
// void resize(size_type sz);
14+
1115
// This test file validates that std::vector<T>::resize(size_type) provides the strong exception guarantee
1216
// if no exception is thrown by the move constructor of T during the resize call. It also checks that if
1317
// T's move constructor is not noexcept, resize provides only the basic exception guarantee.
@@ -35,7 +39,8 @@ void test_allocation_exception_for_strong_guarantee(
3539
std::size_t old_cap = v.capacity();
3640

3741
try {
38-
v.resize(new_size);
42+
v.resize(new_size); // Expected exception
43+
assert(false);
3944
} catch (...) { // std::length_error, std::bad_alloc
4045
assert(v.data() == old_data);
4146
assert(v.size() == old_size);
@@ -60,7 +65,8 @@ void test_default_ctor_exception_for_strong_guarantee(
6065
std::size_t new_size = old_size + 1;
6166

6267
try {
63-
v.resize(new_size);
68+
v.resize(new_size); // Expected exception
69+
assert(false);
6470
} catch (...) {
6571
assert(v.data() == old_data);
6672
assert(v.size() == old_size);
@@ -85,7 +91,8 @@ void test_copy_ctor_exception_for_strong_guarantee(std::vector<throwing_data<T>,
8591
std::size_t new_size = 2 * old_cap;
8692

8793
try {
88-
v.resize(new_size);
94+
v.resize(new_size); // Expected exception
95+
assert(false);
8996
} catch (...) {
9097
assert(v.data() == old_data);
9198
assert(v.size() == old_size);
@@ -107,7 +114,8 @@ void test_move_ctor_exception_for_basic_guarantee(std::vector<move_only_throwing
107114
v.emplace_back(values[i], throw_after);
108115

109116
try {
110-
v.resize(2 * v.capacity());
117+
v.resize(2 * v.capacity()); // Expected exception
118+
assert(false);
111119
} catch (...) {
112120
use_unspecified_but_valid_state_vector(v);
113121
}

libcxx/test/std/containers/sequences/vector/vector.capacity/resize_size_value_exceptions.pass.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
// UNSUPPORTED: no-exceptions
1010

11+
// <vector>
12+
13+
// void resize(size_type sz, const value_type& x);
14+
1115
// Check that std::vector<T>::resize(size_type sz, const value_type& x) provides the strong exception guarantee
1216
// if T is Cpp17CopyInsertable.
1317

@@ -33,7 +37,8 @@ void test_allocation_exception_for_strong_guarantee(
3337
std::size_t old_cap = v.capacity();
3438

3539
try {
36-
v.resize(new_size, values.empty() ? T() : values[0]);
40+
v.resize(new_size, values.empty() ? T() : values[0]); // Expected exception
41+
assert(false);
3742
} catch (...) { // std::length_error, std::bad_alloc
3843
assert(v.data() == old_data);
3944
assert(v.size() == old_size);
@@ -60,7 +65,8 @@ void test_copy_ctor_exception_for_strong_guarantee(std::vector<throwing_data<T>,
6065
try {
6166
int n = new_size - old_size + 1;
6267
throwing_data<T> t(T(), n);
63-
v.resize(new_size, t);
68+
v.resize(new_size, t); // Expected exception
69+
assert(false);
6470
} catch (...) {
6571
assert(v.data() == old_data);
6672
assert(v.size() == old_size);

libcxx/test/std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
// UNSUPPORTED: no-exceptions
1010

11+
// <vector>
12+
13+
// void shrink_to_fit();
14+
1115
// This test file validates that std::vector<T>::shrink_to_fit provides the strong exception guarantee when
1216
// T is Cpp17MoveInsertable and its move constructor does not throw exceptions during the shrink_to_fit
1317
// call. Additionally, it checks that for move-only types where T's move constructor is not noexcept, only
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
// UNSUPPORTED: no-exceptions
11+
12+
// template<container-compatible-range<T> R>
13+
// constexpr void append_range(R&& rg); // C++23
14+
15+
#include <cassert>
16+
#include <vector>
17+
18+
#include "test_allocator.h"
19+
20+
void test() {
21+
{
22+
std::vector<int, limited_allocator<int, 10> > v(8, 42);
23+
int a[] = {1, 2, 3};
24+
try {
25+
v.append_range(a);
26+
assert(false);
27+
} catch (...) {
28+
assert(v.size() == 8);
29+
for (std::size_t i = 0; i != v.size(); ++i)
30+
assert(v[i] == 42);
31+
}
32+
}
33+
}
34+
35+
int main(int, char**) {
36+
test();
37+
38+
return 0;
39+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: no-exceptions
10+
11+
// <vector>
12+
13+
// template <class... Args>
14+
// reference emplace_back(Args&&... args); // reference in C++17
15+
16+
#include <cassert>
17+
#include <vector>
18+
19+
#include "test_allocator.h"
20+
21+
int main(int, char**) {
22+
std::vector<int, limited_allocator<int, 10> > v(10, 42);
23+
try {
24+
v.emplace_back(0);
25+
assert(false);
26+
} catch (...) {
27+
assert(v.size() == v.max_size());
28+
for (std::size_t i = 0; i != v.size(); ++i)
29+
assert(v[i] == 42); // Strong exception safety guarantee
30+
}
31+
32+
return 0;
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: no-exceptions
10+
11+
// <vector>
12+
13+
// template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
14+
15+
#include <cassert>
16+
#include <vector>
17+
18+
#include "test_allocator.h"
19+
20+
void test() {
21+
{
22+
std::vector<int, limited_allocator<int, 10> > v(10, 42);
23+
try {
24+
v.emplace(v.begin(), 0);
25+
assert(false);
26+
} catch (...) {
27+
assert(v.size() == v.max_size());
28+
for (std::size_t i = 0; i != v.size(); ++i)
29+
assert(v[i] == 42);
30+
}
31+
}
32+
{
33+
std::vector<int, limited_allocator<int, 10> > v(10, 42);
34+
try {
35+
v.emplace(v.end(), 0);
36+
assert(false);
37+
} catch (...) {
38+
assert(v.size() == v.max_size());
39+
for (std::size_t i = 0; i != v.size(); ++i)
40+
assert(v[i] == 42);
41+
}
42+
}
43+
}
44+
45+
int main(int, char**) {
46+
test();
47+
48+
return 0;
49+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: no-exceptions
10+
11+
// <vector>
12+
13+
// iterator insert(const_iterator position, const value_type& x);
14+
// iterator insert(const_iterator position, size_type n, const value_type& x);
15+
// iterator insert(const_iterator p, initializer_list<value_type> il);
16+
// template <class Iter>
17+
// iterator insert(const_iterator position, Iter first, Iter last);
18+
19+
#include <cassert>
20+
#include <vector>
21+
22+
#include "test_allocator.h"
23+
24+
void test() {
25+
{
26+
std::vector<int, limited_allocator<int, 10> > v(10, 42);
27+
try {
28+
v.insert(v.begin(), 0);
29+
assert(false);
30+
} catch (...) {
31+
assert(v.size() == v.max_size());
32+
for (std::size_t i = 0; i != v.size(); ++i)
33+
assert(v[i] == 42);
34+
}
35+
}
36+
{
37+
std::vector<int, limited_allocator<int, 10> > v(10, 42);
38+
try {
39+
v.insert(v.end(), 0);
40+
assert(false);
41+
} catch (...) {
42+
assert(v.size() == v.max_size());
43+
for (std::size_t i = 0; i != v.size(); ++i)
44+
assert(v[i] == 42);
45+
}
46+
}
47+
{
48+
std::vector<int, limited_allocator<int, 10> > v(8, 42);
49+
try {
50+
v.insert(v.begin(), 3, 0);
51+
assert(false);
52+
} catch (...) {
53+
assert(v.size() == 8);
54+
for (std::size_t i = 0; i != v.size(); ++i)
55+
assert(v[i] == 42);
56+
}
57+
}
58+
{
59+
std::vector<int, limited_allocator<int, 10> > v(8, 42);
60+
try {
61+
v.insert(v.begin(), {1, 2, 3});
62+
assert(false);
63+
} catch (...) {
64+
assert(v.size() == 8);
65+
for (std::size_t i = 0; i != v.size(); ++i)
66+
assert(v[i] == 42);
67+
}
68+
}
69+
{
70+
std::vector<int, limited_allocator<int, 10> > v(8, 42);
71+
int a[] = {1, 2, 3};
72+
try {
73+
v.insert(v.begin(), a, a + 3);
74+
assert(false);
75+
} catch (...) {
76+
assert(v.size() == 8);
77+
for (std::size_t i = 0; i != v.size(); ++i)
78+
assert(v[i] == 42);
79+
}
80+
}
81+
}
82+
83+
int main(int, char**) {
84+
test();
85+
86+
return 0;
87+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
// UNSUPPORTED: no-exceptions
11+
12+
// template<container-compatible-range<T> R>
13+
// constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
14+
15+
#include <cassert>
16+
#include <vector>
17+
18+
#include "test_allocator.h"
19+
20+
void test() {
21+
{
22+
std::vector<int, limited_allocator<int, 10> > v(8, 42);
23+
int a[] = {1, 2, 3};
24+
try {
25+
v.insert_range(v.begin(), a);
26+
assert(false);
27+
} catch (...) {
28+
assert(v.size() == 8);
29+
for (std::size_t i = 0; i != v.size(); ++i)
30+
assert(v[i] == 42);
31+
}
32+
}
33+
{
34+
std::vector<int, limited_allocator<int, 10> > v(8, 42);
35+
int a[] = {1, 2, 3};
36+
try {
37+
v.insert_range(v.end(), a);
38+
assert(false);
39+
} catch (...) {
40+
assert(v.size() == 8);
41+
for (std::size_t i = 0; i != v.size(); ++i)
42+
assert(v[i] == 42);
43+
}
44+
}
45+
}
46+
47+
int main(int, char**) {
48+
test();
49+
50+
return 0;
51+
}

0 commit comments

Comments
 (0)