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 
23 struct A
24 {
25     static int constructed;
26 
AA27     A() {++constructed;}
~AA28     ~A() {--constructed;}
AA29     A(const A&)  {++constructed;}
30 };
31 
32 int A::constructed = 0;
33 
main(int,char **)34 int 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