annotate libstdc++-v3/libsupc++/eh_ptr.cc @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // -*- C++ -*- Implement the members of exception_ptr.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 // Copyright (C) 2008-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 //
kono
parents:
diff changeset
4 // This file is part of GCC.
kono
parents:
diff changeset
5 //
kono
parents:
diff changeset
6 // GCC is free software; you can redistribute it and/or modify
kono
parents:
diff changeset
7 // it under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
8 // the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
9 // any later version.
kono
parents:
diff changeset
10 //
kono
parents:
diff changeset
11 // GCC is distributed in the hope that it will be useful,
kono
parents:
diff changeset
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
14 // GNU General Public License for more details.
kono
parents:
diff changeset
15 //
kono
parents:
diff changeset
16 // Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
17 // permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
18 // 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 // You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
21 // a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
23 // <http://www.gnu.org/licenses/>.
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 #include <bits/c++config.h>
kono
parents:
diff changeset
26 #include "eh_atomics.h"
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #define _GLIBCXX_EH_PTR_COMPAT
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 #include <exception>
kono
parents:
diff changeset
31 #include <bits/exception_ptr.h>
kono
parents:
diff changeset
32 #include "unwind-cxx.h"
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 using namespace __cxxabiv1;
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 // Verify assumptions about member layout in exception types
kono
parents:
diff changeset
37 namespace
kono
parents:
diff changeset
38 {
kono
parents:
diff changeset
39 template<typename Ex>
kono
parents:
diff changeset
40 constexpr std::size_t unwindhdr()
kono
parents:
diff changeset
41 { return offsetof(Ex, unwindHeader); }
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 template<typename Ex>
kono
parents:
diff changeset
44 constexpr std::size_t termHandler()
kono
parents:
diff changeset
45 { return unwindhdr<Ex>() - offsetof(Ex, terminateHandler); }
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 static_assert( termHandler<__cxa_exception>()
kono
parents:
diff changeset
48 == termHandler<__cxa_dependent_exception>(),
kono
parents:
diff changeset
49 "__cxa_dependent_exception::termHandler layout must be"
kono
parents:
diff changeset
50 " consistent with __cxa_exception::termHandler" );
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 #ifndef __ARM_EABI_UNWINDER__
kono
parents:
diff changeset
53 template<typename Ex>
kono
parents:
diff changeset
54 constexpr std::ptrdiff_t adjptr()
kono
parents:
diff changeset
55 { return unwindhdr<Ex>() - offsetof(Ex, adjustedPtr); }
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 static_assert( adjptr<__cxa_exception>()
kono
parents:
diff changeset
58 == adjptr<__cxa_dependent_exception>(),
kono
parents:
diff changeset
59 "__cxa_dependent_exception::adjustedPtr layout must be"
kono
parents:
diff changeset
60 " consistent with __cxa_exception::adjustedPtr" );
kono
parents:
diff changeset
61 #endif
kono
parents:
diff changeset
62 }
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 std::__exception_ptr::exception_ptr::exception_ptr() noexcept
kono
parents:
diff changeset
65 : _M_exception_object(0) { }
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 std::__exception_ptr::exception_ptr::exception_ptr(void* obj) noexcept
kono
parents:
diff changeset
69 : _M_exception_object(obj) { _M_addref(); }
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 std::__exception_ptr::exception_ptr::exception_ptr(__safe_bool) noexcept
kono
parents:
diff changeset
73 : _M_exception_object(0) { }
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 std::__exception_ptr::
kono
parents:
diff changeset
77 exception_ptr::exception_ptr(const exception_ptr& other) noexcept
kono
parents:
diff changeset
78 : _M_exception_object(other._M_exception_object)
kono
parents:
diff changeset
79 { _M_addref(); }
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 std::__exception_ptr::exception_ptr::~exception_ptr() noexcept
kono
parents:
diff changeset
83 { _M_release(); }
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 std::__exception_ptr::exception_ptr&
kono
parents:
diff changeset
87 std::__exception_ptr::
kono
parents:
diff changeset
88 exception_ptr::operator=(const exception_ptr& other) noexcept
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 exception_ptr(other).swap(*this);
kono
parents:
diff changeset
91 return *this;
kono
parents:
diff changeset
92 }
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 void
kono
parents:
diff changeset
96 std::__exception_ptr::exception_ptr::_M_addref() noexcept
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 if (_M_exception_object)
kono
parents:
diff changeset
99 {
kono
parents:
diff changeset
100 __cxa_refcounted_exception *eh =
kono
parents:
diff changeset
101 __get_refcounted_exception_header_from_obj (_M_exception_object);
kono
parents:
diff changeset
102 __gnu_cxx::__eh_atomic_inc (&eh->referenceCount);
kono
parents:
diff changeset
103 }
kono
parents:
diff changeset
104 }
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 void
kono
parents:
diff changeset
108 std::__exception_ptr::exception_ptr::_M_release() noexcept
kono
parents:
diff changeset
109 {
kono
parents:
diff changeset
110 if (_M_exception_object)
kono
parents:
diff changeset
111 {
kono
parents:
diff changeset
112 __cxa_refcounted_exception *eh =
kono
parents:
diff changeset
113 __get_refcounted_exception_header_from_obj (_M_exception_object);
kono
parents:
diff changeset
114 if (__gnu_cxx::__eh_atomic_dec (&eh->referenceCount))
kono
parents:
diff changeset
115 {
kono
parents:
diff changeset
116 if (eh->exc.exceptionDestructor)
kono
parents:
diff changeset
117 eh->exc.exceptionDestructor (_M_exception_object);
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 __cxa_free_exception (_M_exception_object);
kono
parents:
diff changeset
120 _M_exception_object = 0;
kono
parents:
diff changeset
121 }
kono
parents:
diff changeset
122 }
kono
parents:
diff changeset
123 }
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 void*
kono
parents:
diff changeset
127 std::__exception_ptr::exception_ptr::_M_get() const noexcept
kono
parents:
diff changeset
128 { return _M_exception_object; }
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 void
kono
parents:
diff changeset
132 std::__exception_ptr::exception_ptr::swap(exception_ptr &other) noexcept
kono
parents:
diff changeset
133 {
kono
parents:
diff changeset
134 void *tmp = _M_exception_object;
kono
parents:
diff changeset
135 _M_exception_object = other._M_exception_object;
kono
parents:
diff changeset
136 other._M_exception_object = tmp;
kono
parents:
diff changeset
137 }
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 // Retained for compatibility with CXXABI_1.3.
kono
parents:
diff changeset
141 void
kono
parents:
diff changeset
142 std::__exception_ptr::exception_ptr::_M_safe_bool_dummy() noexcept { }
kono
parents:
diff changeset
143
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 // Retained for compatibility with CXXABI_1.3.
kono
parents:
diff changeset
146 bool
kono
parents:
diff changeset
147 std::__exception_ptr::exception_ptr::operator!() const noexcept
kono
parents:
diff changeset
148 { return _M_exception_object == 0; }
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 // Retained for compatibility with CXXABI_1.3.
kono
parents:
diff changeset
152 std::__exception_ptr::exception_ptr::operator __safe_bool() const noexcept
kono
parents:
diff changeset
153 {
kono
parents:
diff changeset
154 return _M_exception_object ? &exception_ptr::_M_safe_bool_dummy : 0;
kono
parents:
diff changeset
155 }
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 const std::type_info*
kono
parents:
diff changeset
159 std::__exception_ptr::exception_ptr::__cxa_exception_type() const noexcept
kono
parents:
diff changeset
160 {
kono
parents:
diff changeset
161 __cxa_exception *eh = __get_exception_header_from_obj (_M_exception_object);
kono
parents:
diff changeset
162 return eh->exceptionType;
kono
parents:
diff changeset
163 }
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 bool std::__exception_ptr::operator==(const exception_ptr& lhs,
kono
parents:
diff changeset
167 const exception_ptr& rhs) noexcept
kono
parents:
diff changeset
168 { return lhs._M_exception_object == rhs._M_exception_object; }
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 bool std::__exception_ptr::operator!=(const exception_ptr& lhs,
kono
parents:
diff changeset
172 const exception_ptr& rhs) noexcept
kono
parents:
diff changeset
173 { return !(lhs == rhs);}
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 std::exception_ptr
kono
parents:
diff changeset
177 std::current_exception() noexcept
kono
parents:
diff changeset
178 {
kono
parents:
diff changeset
179 __cxa_eh_globals *globals = __cxa_get_globals ();
kono
parents:
diff changeset
180 __cxa_exception *header = globals->caughtExceptions;
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 if (!header)
kono
parents:
diff changeset
183 return std::exception_ptr();
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 // Since foreign exceptions can't be counted, we can't return them.
kono
parents:
diff changeset
186 if (!__is_gxx_exception_class (header->unwindHeader.exception_class))
kono
parents:
diff changeset
187 return std::exception_ptr();
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 return std::exception_ptr(
kono
parents:
diff changeset
190 __get_object_from_ambiguous_exception (header));
kono
parents:
diff changeset
191 }
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 static void
kono
parents:
diff changeset
195 __gxx_dependent_exception_cleanup(_Unwind_Reason_Code code,
kono
parents:
diff changeset
196 _Unwind_Exception *exc)
kono
parents:
diff changeset
197 {
kono
parents:
diff changeset
198 // This cleanup is set only for dependents.
kono
parents:
diff changeset
199 __cxa_dependent_exception *dep = __get_dependent_exception_from_ue (exc);
kono
parents:
diff changeset
200 __cxa_refcounted_exception *header =
kono
parents:
diff changeset
201 __get_refcounted_exception_header_from_obj (dep->primaryException);
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 // We only want to be called through _Unwind_DeleteException.
kono
parents:
diff changeset
204 // _Unwind_DeleteException in the HP-UX IA64 libunwind library
kono
parents:
diff changeset
205 // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
kono
parents:
diff changeset
206 // like the GCC _Unwind_DeleteException function does.
kono
parents:
diff changeset
207 if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
kono
parents:
diff changeset
208 __terminate (header->exc.terminateHandler);
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 __cxa_free_dependent_exception (dep);
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 if (__gnu_cxx::__eh_atomic_dec (&header->referenceCount))
kono
parents:
diff changeset
213 {
kono
parents:
diff changeset
214 if (header->exc.exceptionDestructor)
kono
parents:
diff changeset
215 header->exc.exceptionDestructor (header + 1);
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 __cxa_free_exception (header + 1);
kono
parents:
diff changeset
218 }
kono
parents:
diff changeset
219 }
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 void
kono
parents:
diff changeset
223 std::rethrow_exception(std::exception_ptr ep)
kono
parents:
diff changeset
224 {
kono
parents:
diff changeset
225 void *obj = ep._M_get();
kono
parents:
diff changeset
226 __cxa_refcounted_exception *eh
kono
parents:
diff changeset
227 = __get_refcounted_exception_header_from_obj (obj);
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception ();
kono
parents:
diff changeset
230 dep->primaryException = obj;
kono
parents:
diff changeset
231 __gnu_cxx::__eh_atomic_inc (&eh->referenceCount);
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 dep->unexpectedHandler = get_unexpected ();
kono
parents:
diff changeset
234 dep->terminateHandler = get_terminate ();
kono
parents:
diff changeset
235 __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(dep->unwindHeader.exception_class);
kono
parents:
diff changeset
236 dep->unwindHeader.exception_cleanup = __gxx_dependent_exception_cleanup;
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 __cxa_eh_globals *globals = __cxa_get_globals ();
kono
parents:
diff changeset
239 globals->uncaughtExceptions += 1;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 #ifdef __USING_SJLJ_EXCEPTIONS__
kono
parents:
diff changeset
242 _Unwind_SjLj_RaiseException (&dep->unwindHeader);
kono
parents:
diff changeset
243 #else
kono
parents:
diff changeset
244 _Unwind_RaiseException (&dep->unwindHeader);
kono
parents:
diff changeset
245 #endif
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 // Some sort of unwinding error. Note that terminate is a handler.
kono
parents:
diff changeset
248 __cxa_begin_catch (&dep->unwindHeader);
kono
parents:
diff changeset
249 std::terminate();
kono
parents:
diff changeset
250 }
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 #undef _GLIBCXX_EH_PTR_COMPAT