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