]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / libcxx / containers / sequences / vector / asan_throw.pass.cpp
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: libcpp-no-exceptions
11 // Test asan vector annotations with a class that throws in a CTOR.
12
13 #include <vector>
14 #include <cassert>
15
16 #include "asan_testing.h"
17
18 class X {
19 public:
20   X(const X &x) { Init(x.a); }
21   X(char arg) { Init(arg); }
22   X() { Init(42); }
23   X &operator=(const X &x) {
24     Init(x.a);
25     return *this;
26   }
27   void Init(char arg) {
28     if (arg == 42)
29       throw 0;
30     if (arg == 66)
31       arg = 42;
32     a = arg;
33   }
34   char get() const { return a; }
35   void set(char arg) { a = arg; }
36
37 private:
38   char a;
39 };
40
41 class ThrowOnCopy {
42 public:
43     ThrowOnCopy() : should_throw(false) {}
44     explicit ThrowOnCopy(bool xshould_throw) : should_throw(xshould_throw) {}
45
46     ThrowOnCopy(ThrowOnCopy const & other)
47         : should_throw(other.should_throw)
48     {
49         if (should_throw) {
50             throw 0;
51         }
52     }
53
54     bool should_throw;
55 };
56
57 void test_push_back() {
58   std::vector<X> v;
59   v.reserve(2);
60   v.push_back(X(2));
61   assert(v.size() == 1);
62   try {
63     v.push_back(X(66));
64     assert(0);
65   } catch (int e) {
66     assert(v.size() == 1);
67   }
68   assert(v.size() == 1);
69   assert(is_contiguous_container_asan_correct(v));
70 }
71
72 void test_emplace_back() {
73 #ifndef _LIBCPP_HAS_NO_VARIADICS
74   std::vector<X> v;
75   v.reserve(2);
76   v.push_back(X(2));
77   assert(v.size() == 1);
78   try {
79     v.emplace_back(42);
80     assert(0);
81   } catch (int e) {
82     assert(v.size() == 1);
83   }
84   assert(v.size() == 1);
85   assert(is_contiguous_container_asan_correct(v));
86 #endif // _LIBCPP_HAS_NO_VARIADICS
87 }
88
89 void test_insert_range() {
90   std::vector<X> v;
91   v.reserve(4);
92   v.push_back(X(1));
93   v.push_back(X(2));
94   assert(v.size() == 2);
95   assert(v.capacity() >= 4);
96   try {
97     char a[2] = {21, 42};
98     v.insert(v.end(), a, a + 2);
99     assert(0);
100   } catch (int e) {
101     assert(v.size() == 3);
102   }
103   assert(v.size() == 3);
104   assert(is_contiguous_container_asan_correct(v));
105 }
106
107 void test_insert() {
108   std::vector<X> v;
109   v.reserve(3);
110   v.insert(v.end(), X(1));
111   v.insert(v.begin(), X(2));
112   assert(v.size() == 2);
113   try {
114     v.insert(v.end(), X(66));
115     assert(0);
116   } catch (int e) {
117     assert(v.size() == 2);
118   }
119   assert(v.size() == 2);
120   assert(is_contiguous_container_asan_correct(v));
121 }
122
123 void test_emplace() {
124 #ifndef _LIBCPP_HAS_NO_VARIADICS
125   std::vector<X> v;
126   v.reserve(3);
127   v.insert(v.end(), X(1));
128   v.insert(v.begin(), X(2));
129   assert(v.size() == 2);
130   try {
131     v.emplace(v.end(), 42);
132     assert(0);
133   } catch (int e) {
134     assert(v.size() == 2);
135   }
136   assert(v.size() == 2);
137   assert(is_contiguous_container_asan_correct(v));
138 #endif // _LIBCPP_HAS_NO_VARIADICS
139 }
140
141 void test_insert_range2() {
142   std::vector<X> v;
143   v.reserve(4);
144   v.insert(v.end(), X(1));
145   v.insert(v.begin(), X(2));
146   assert(v.size() == 2);
147   assert(v.capacity() >= 4);
148   try {
149     char a[2] = {10, 42};
150     v.insert(v.begin(), a, a + 2);
151     assert(0);
152   } catch (int e) {
153     assert(v.size() <= 4);
154     assert(is_contiguous_container_asan_correct(v));
155     return;
156   }
157   assert(0);
158 }
159
160 void test_insert_n() {
161   std::vector<X> v;
162   v.reserve(10);
163   v.insert(v.end(), X(1));
164   v.insert(v.begin(), X(2));
165   assert(v.size() == 2);
166   try {
167     v.insert(v.begin(), 1, X(66));
168     assert(0);
169   } catch (int e) {
170     assert(v.size() <= 3);
171     assert(is_contiguous_container_asan_correct(v));
172     return;
173   }
174   assert(0);
175 }
176
177
178 void test_insert_n2() {
179   std::vector<ThrowOnCopy> v(10);
180   v.reserve(100);
181   assert(v.size() == 10);
182   v[6].should_throw = true;
183   try {
184     v.insert(v.cbegin(), 5, ThrowOnCopy());
185     assert(0);
186   } catch (int e) {
187     assert(v.size() == 11);
188     assert(is_contiguous_container_asan_correct(v));
189     return;
190   }
191   assert(0);
192 }
193
194 void test_resize() {
195   std::vector<X> v;
196   v.reserve(3);
197   v.push_back(X(0));
198   try {
199     v.resize(3);
200     assert(0);
201   } catch (int e) {
202     assert(v.size() == 1);
203   }
204   assert(v.size() == 1);
205   assert(is_contiguous_container_asan_correct(v));
206 }
207
208 void test_resize_param() {
209   std::vector<X> v;
210   v.reserve(3);
211   v.push_back(X(0));
212   try {
213     v.resize(3, X(66));
214     assert(0);
215   } catch (int e) {
216     assert(v.size() == 1);
217   }
218   assert(v.size() == 1);
219   assert(is_contiguous_container_asan_correct(v));
220 }
221
222 int main() {
223   test_push_back();
224   test_emplace_back();
225   test_insert_range();
226   test_insert();
227   test_emplace();
228   test_insert_range2();
229   test_insert_n();
230   test_insert_n2();
231   test_resize();
232   test_resize_param();
233 }