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