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