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// FIXME: This test needs to be rewritten for the MSVC exception_ptr semantics
10// which copy the exception each time the exception_ptr is copied.
11// XFAIL: msvc
12
13// UNSUPPORTED: no-exceptions
14// <exception>
15
16// exception_ptr current_exception();
17
18#include <exception>
19#include <cassert>
20
21#include "test_macros.h"
22
23struct A
24{
25 static int constructed;
26
27 A() {++constructed;}
28 ~A() {--constructed;}
29 A(const A&) {++constructed;}
30};
31
32int A::constructed = 0;
33
34int main(int, char**)
35{
36 {
37 std::exception_ptr p = std::current_exception();
38 assert(p == nullptr);
39 }
40 {
41 try
42 {
43 assert(A::constructed == 0);
44 throw A();
45 assert(false);
46 }
47 catch (...)
48 {
49 assert(A::constructed == 1);
50 }
51 assert(A::constructed == 0);
52 }
53 assert(A::constructed == 0);
54 {
55 std::exception_ptr p2;
56 try
57 {
58 assert(A::constructed == 0);
59 throw A();
60 assert(false);
61 }
62 catch (...)
63 {
64 std::exception_ptr p = std::current_exception();
65 assert(A::constructed == 1);
66 assert(p != nullptr);
67 p2 = std::current_exception();
68 assert(A::constructed == 1);
69 assert(p == p2);
70 }
71 assert(A::constructed == 1);
72 }
73 assert(A::constructed == 0);
74 {
75 std::exception_ptr p2;
76 try
77 {
78 assert(A::constructed == 0);
79 throw A();
80 assert(false);
81 }
82 catch (A&)
83 {
84 std::exception_ptr p = std::current_exception();
85 assert(A::constructed == 1);
86 assert(p != nullptr);
87 p2 = std::current_exception();
88 assert(A::constructed == 1);
89 assert(p == p2);
90 }
91 assert(A::constructed == 1);
92 }
93 assert(A::constructed == 0);
94 {
95 std::exception_ptr p2;
96 try
97 {
98 assert(A::constructed == 0);
99 throw A();
100 assert(false);
101 }
102 catch (A)
103 {
104 std::exception_ptr p = std::current_exception();
105 assert(A::constructed == 2);
106 assert(p != nullptr);
107 p2 = std::current_exception();
108 assert(A::constructed == 2);
109 assert(p == p2);
110 }
111 assert(A::constructed == 1);
112 }
113 assert(A::constructed == 0);
114 {
115 try
116 {
117 assert(A::constructed == 0);
118 throw A();
119 assert(false);
120 }
121 catch (...)
122 {
123 assert(A::constructed == 1);
124 try
125 {
126 assert(A::constructed == 1);
127 throw;
128 assert(false);
129 }
130 catch (...)
131 {
132 assert(A::constructed == 1);
133 }
134 assert(A::constructed == 1);
135 }
136 assert(A::constructed == 0);
137 }
138 assert(A::constructed == 0);
139 {
140 try
141 {
142 assert(A::constructed == 0);
143 throw A();
144 assert(false);
145 }
146 catch (...)
147 {
148 assert(A::constructed == 1);
149 try
150 {
151 std::exception_ptr p = std::current_exception();
152 assert(A::constructed == 1);
153 assert(p != nullptr);
154 throw;
155 assert(false);
156 }
157 catch (...)
158 {
159 assert(A::constructed == 1);
160 }
161 assert(A::constructed == 1);
162 }
163 assert(A::constructed == 0);
164 }
165 assert(A::constructed == 0);
166 {
167 try
168 {
169 assert(A::constructed == 0);
170 throw A();
171 assert(false);
172 }
173 catch (...)
174 {
175 assert(A::constructed == 1);
176 try
177 {
178 assert(A::constructed == 1);
179 throw;
180 assert(false);
181 }
182 catch (...)
183 {
184 std::exception_ptr p = std::current_exception();
185 assert(A::constructed == 1);
186 assert(p != nullptr);
187 }
188 assert(A::constructed == 1);
189 }
190 assert(A::constructed == 0);
191 }
192 assert(A::constructed == 0);
193 {
194 try
195 {
196 assert(A::constructed == 0);
197 throw A();
198 assert(false);
199 }
200 catch (...)
201 {
202 assert(A::constructed == 1);
203 try
204 {
205 assert(A::constructed == 1);
206 throw;
207 assert(false);
208 }
209 catch (...)
210 {
211 assert(A::constructed == 1);
212 }
213 std::exception_ptr p = std::current_exception();
214 assert(A::constructed == 1);
215 assert(p != nullptr);
216 }
217 assert(A::constructed == 0);
218 }
219 assert(A::constructed == 0);
220 {
221 try
222 {
223 assert(A::constructed == 0);
224 throw A();
225 assert(false);
226 }
227 catch (...)
228 {
229 assert(A::constructed == 1);
230 try
231 {
232 assert(A::constructed == 1);
233 throw;
234 assert(false);
235 }
236 catch (...)
237 {
238 assert(A::constructed == 1);
239 }
240 assert(A::constructed == 1);
241 }
242 std::exception_ptr p = std::current_exception();
243 assert(A::constructed == 0);
244 assert(p == nullptr);
245 }
246 assert(A::constructed == 0);
247 {
248 std::exception_ptr p;
249 try
250 {
251 assert(A::constructed == 0);
252 throw A();
253 assert(false);
254 }
255 catch (...)
256 {
257 assert(A::constructed == 1);
258 try
259 {
260 assert(A::constructed == 1);
261 throw;
262 assert(false);
263 }
264 catch (...)
265 {
266 p = std::current_exception();
267 assert(A::constructed == 1);
268 }
269 assert(A::constructed == 1);
270 }
271 assert(A::constructed == 1);
272 assert(p != nullptr);
273 }
274 assert(A::constructed == 0);
275
276 return 0;
277}
278

source code of libcxx/test/std/language.support/support.exception/propagation/current_exception.pass.cpp