Skip to content

Commit 679d36c

Browse files
committed
Validate exception throwing for vector mutators on max_size violation
1 parent bda87e0 commit 679d36c

24 files changed

+939
-40
lines changed

libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,5 @@ int main(int, char**) {
6565
test();
6666
static_assert(test());
6767

68-
// Note: `test_append_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
69-
test_append_range_exception_safety_throwing_allocator<std::vector, bool>();
70-
7168
return 0;
7269
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
// <vector>
13+
// vector<bool>
14+
15+
// template<container-compatible-range<bool> R>
16+
// constexpr void append_range(R&& rg); // C++23
17+
18+
#include <cassert>
19+
#include <vector>
20+
21+
#include "../insert_range_sequence_containers.h"
22+
#include "test_allocator.h"
23+
24+
void test() {
25+
// Note: `test_append_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
26+
test_append_range_exception_safety_throwing_allocator<std::vector, bool>();
27+
28+
{
29+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
30+
Vec v(Vec().max_size() - 2, true);
31+
bool a[] = {false, true, false};
32+
try {
33+
v.append_range(a);
34+
assert(false);
35+
} catch (const std::length_error&) {
36+
assert(v.size() == v.max_size() - 2);
37+
for (std::size_t i = 0; i < v.size(); ++i)
38+
assert(v[i] == true);
39+
}
40+
}
41+
{
42+
std::vector<bool, limited_allocator<bool, 10> > v(10, true);
43+
bool a[10 * 65536] = {};
44+
try {
45+
v.append_range(a);
46+
assert(false);
47+
} catch (...) {
48+
assert(v.size() == 10);
49+
for (std::size_t i = 0; i != v.size(); ++i)
50+
assert(v[i] == true);
51+
}
52+
}
53+
}
54+
55+
int main(int, char**) {
56+
test();
57+
58+
return 0;
59+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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
10+
// UNSUPPORTED: no-exceptions
11+
12+
// <vector>
13+
// vector<bool>
14+
15+
// template <class... Args>
16+
// reference emplace_back(Args&&... args); // reference in C++17
17+
18+
#include <cassert>
19+
#include <vector>
20+
21+
#include "test_allocator.h"
22+
23+
int main(int, char**) {
24+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
25+
Vec v(Vec().max_size(), true);
26+
try {
27+
v.emplace_back(true);
28+
assert(false);
29+
} catch (...) {
30+
assert(v.size() == v.max_size());
31+
for (std::size_t i = 0; i != v.size(); ++i)
32+
assert(v[i] == true);
33+
}
34+
35+
return 0;
36+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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
10+
// UNSUPPORTED: no-exceptions
11+
12+
// <vector>
13+
// vector<bool>
14+
15+
// template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
16+
17+
#include <cassert>
18+
#include <vector>
19+
20+
#include "test_allocator.h"
21+
22+
void test() {
23+
{
24+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
25+
Vec v(Vec().max_size(), true);
26+
try {
27+
v.emplace(v.begin(), true);
28+
assert(false);
29+
} catch (...) {
30+
assert(v.size() == v.max_size());
31+
for (std::size_t i = 0; i != v.size(); ++i)
32+
assert(v[i] == true);
33+
}
34+
}
35+
{
36+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
37+
Vec v(Vec().max_size(), true);
38+
try {
39+
v.emplace(v.end(), true);
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] == true);
45+
}
46+
}
47+
{
48+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
49+
Vec v(Vec().max_size(), true);
50+
try {
51+
v.emplace(v.begin() + v.size() / 2, true);
52+
assert(false);
53+
} catch (...) {
54+
assert(v.size() == v.max_size());
55+
for (std::size_t i = 0; i != v.size(); ++i)
56+
assert(v[i] == true);
57+
}
58+
}
59+
}
60+
61+
int main(int, char**) {
62+
test();
63+
64+
return 0;
65+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
// vector<bool>
13+
14+
// iterator insert(const_iterator position, const value_type& x);
15+
// iterator insert(const_iterator position, size_type n, const value_type& x);
16+
// iterator insert(const_iterator p, initializer_list<value_type> il);
17+
// template <class Iter>
18+
// iterator insert(const_iterator position, Iter first, Iter last);
19+
20+
#include <cassert>
21+
#include <vector>
22+
23+
#include "test_allocator.h"
24+
#include "test_macros.h"
25+
26+
void test() {
27+
{
28+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
29+
Vec v(Vec().max_size(), true);
30+
try {
31+
v.insert(v.begin(), false);
32+
assert(false);
33+
} catch (...) {
34+
assert(v.size() == v.max_size());
35+
for (std::size_t i = 0; i != v.size(); ++i)
36+
assert(v[i] == true);
37+
}
38+
}
39+
{
40+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
41+
Vec v(Vec().max_size(), false);
42+
try {
43+
v.insert(v.end(), 0);
44+
assert(false);
45+
} catch (...) {
46+
assert(v.size() == v.max_size());
47+
for (std::size_t i = 0; i != v.size(); ++i)
48+
assert(v[i] == false);
49+
}
50+
}
51+
{
52+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
53+
Vec v(Vec().max_size(), true);
54+
try {
55+
v.insert(v.begin() + v.size() / 2, false);
56+
assert(false);
57+
} catch (...) {
58+
assert(v.size() == v.max_size());
59+
for (std::size_t i = 0; i != v.size(); ++i)
60+
assert(v[i] == true);
61+
}
62+
}
63+
{
64+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
65+
Vec v(Vec().max_size(), true);
66+
try {
67+
v.insert(v.begin(), 1, false);
68+
assert(false);
69+
} catch (...) {
70+
assert(v.size() == v.max_size());
71+
for (std::size_t i = 0; i != v.size(); ++i)
72+
assert(v[i] == true);
73+
}
74+
}
75+
{
76+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
77+
Vec v(Vec().max_size() - 2, true);
78+
bool a[] = {true, false, true};
79+
try {
80+
v.insert(v.begin() + v.size() / 2, std::begin(a), std::end(a));
81+
assert(false);
82+
} catch (...) {
83+
assert(v.size() == v.max_size() - 2);
84+
for (std::size_t i = 0; i != v.size(); ++i)
85+
assert(v[i] == true);
86+
}
87+
}
88+
#if TEST_STD_VER >= 11
89+
{
90+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
91+
Vec v(Vec().max_size() - 2, true);
92+
try {
93+
v.insert(v.begin(), {true, false, true});
94+
assert(false);
95+
} catch (...) {
96+
assert(v.size() == v.max_size() - 2);
97+
for (std::size_t i = 0; i != v.size(); ++i)
98+
assert(v[i] == true);
99+
}
100+
}
101+
#endif
102+
}
103+
104+
int main(int, char**) {
105+
test();
106+
107+
return 0;
108+
}

libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ int main(int, char**) {
8484
test();
8585
static_assert(test());
8686

87-
// Note: `test_insert_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
88-
test_insert_range_exception_safety_throwing_allocator<std::vector, bool>();
89-
9087
#ifndef TEST_HAS_NO_LOCALIZATION
9188
test_counted_istream_view();
9289
#endif
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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+
// <vector>
13+
// vector<bool>
14+
15+
// template<container-compatible-range<T> R>
16+
// constexpr iterator insert_range(const_iterator position, R&& rg); // C++23
17+
18+
#include <cassert>
19+
#include <vector>
20+
21+
#include "../insert_range_sequence_containers.h"
22+
#include "test_allocator.h"
23+
24+
void test() {
25+
// Note: `test_insert_range_exception_safety_throwing_copy` doesn't apply because copying booleans cannot throw.
26+
test_insert_range_exception_safety_throwing_allocator<std::vector, bool>();
27+
28+
{
29+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
30+
Vec v(Vec().max_size() - 2, true);
31+
bool a[] = {true, false, true};
32+
try {
33+
v.insert_range(v.end(), a);
34+
assert(false);
35+
} catch (const std::length_error&) {
36+
assert(v.size() == v.max_size() - 2);
37+
for (std::size_t i = 0; i < v.size(); ++i)
38+
assert(v[i] == true);
39+
}
40+
}
41+
{
42+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
43+
Vec v(Vec().max_size() - 2, false);
44+
bool a[] = {true, false, true};
45+
try {
46+
v.insert_range(v.begin(), a);
47+
assert(false);
48+
} catch (const std::length_error&) {
49+
assert(v.size() == v.max_size() - 2);
50+
for (std::size_t i = 0; i < v.size(); ++i)
51+
assert(v[i] == false);
52+
}
53+
}
54+
{
55+
std::vector<bool, limited_allocator<bool, 10> > v(10, true);
56+
bool a[10 * 65536] = {};
57+
try {
58+
v.insert_range(v.begin() + v.size() / 2, a);
59+
assert(false);
60+
} catch (...) {
61+
assert(v.size() == 10);
62+
for (std::size_t i = 0; i != v.size(); ++i)
63+
assert(v[i] == true);
64+
}
65+
}
66+
}
67+
68+
int main(int, char**) {
69+
test();
70+
71+
return 0;
72+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
// vector<bool>
13+
14+
// void push_back(const value_type& x);
15+
16+
#include <cassert>
17+
#include <vector>
18+
19+
#include "test_allocator.h"
20+
21+
int main(int, char**) {
22+
using Vec = std::vector<bool, limited_allocator<bool, 10> >;
23+
Vec v(Vec().max_size(), true);
24+
try {
25+
v.push_back(true);
26+
assert(false);
27+
} catch (...) {
28+
assert(v.size() == v.max_size());
29+
for (std::size_t i = 0; i != v.size(); ++i)
30+
assert(v[i] == true);
31+
}
32+
33+
return 0;
34+
}

0 commit comments

Comments
 (0)