1 // Exception Handling support header (exception_ptr class) for -*- C++ -*- 2 3 // Copyright (C) 2008-2020 Free Software Foundation, Inc. 4 // 5 // This file is part of GCC. 6 // 7 // GCC is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License as published by 9 // the Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 // 12 // GCC is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file bits/exception_ptr.h 27 * This is an internal header file, included by other library headers. 28 * Do not attempt to use it directly. @headername{exception} 29 */ 30 31 #ifndef _EXCEPTION_PTR_H 32 #define _EXCEPTION_PTR_H 33 34 #pragma GCC visibility push(default) 35 36 #include <bits/c++config.h> 37 #include <bits/exception_defines.h> 38 #include <bits/cxxabi_init_exception.h> 39 #include <typeinfo> 40 #include <new> 41 42 #if __cplusplus >= 201103L 43 # include <bits/move.h> 44 #endif 45 46 extern "C++" { 47 48 namespace std 49 { 50 class type_info; 51 52 /** 53 * @addtogroup exceptions 54 * @{ 55 */ 56 57 namespace __exception_ptr 58 { 59 class exception_ptr; 60 } 61 62 using __exception_ptr::exception_ptr; 63 64 /** Obtain an exception_ptr to the currently handled exception. If there 65 * is none, or the currently handled exception is foreign, return the null 66 * value. 67 */ 68 exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; 69 70 template<typename _Ex> 71 exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; 72 73 /// Throw the object pointed to by the exception_ptr. 74 void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); 75 76 namespace __exception_ptr 77 { 78 using std::rethrow_exception; 79 80 /** 81 * @brief An opaque pointer to an arbitrary exception. 82 * @ingroup exceptions 83 */ 84 class exception_ptr 85 { 86 void* _M_exception_object; 87 88 explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT; 89 90 void _M_addref() _GLIBCXX_USE_NOEXCEPT; 91 void _M_release() _GLIBCXX_USE_NOEXCEPT; 92 93 void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__)); 94 95 friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; 96 friend void std::rethrow_exception(exception_ptr); 97 template<typename _Ex> 98 friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; 99 100 public: 101 exception_ptr() _GLIBCXX_USE_NOEXCEPT; 102 103 exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 104 105 #if __cplusplus >= 201103L 106 exception_ptr(nullptr_t) noexcept 107 : _M_exception_object(0) 108 { } 109 110 exception_ptr(exception_ptr&& __o) noexcept 111 : _M_exception_object(__o._M_exception_object) 112 { __o._M_exception_object = 0; } 113 #endif 114 115 #if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT) 116 typedef void (exception_ptr::*__safe_bool)(); 117 118 // For construction from nullptr or 0. 119 exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT; 120 #endif 121 122 exception_ptr& 123 operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 124 125 #if __cplusplus >= 201103L 126 exception_ptr& 127 operator=(exception_ptr&& __o) noexcept 128 { 129 exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this); 130 return *this; 131 } 132 #endif 133 134 ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; 135 136 void 137 swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT; 138 139 #ifdef _GLIBCXX_EH_PTR_COMPAT 140 // Retained for compatibility with CXXABI_1.3. 141 void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT 142 __attribute__ ((__const__)); 143 bool operator!() const _GLIBCXX_USE_NOEXCEPT 144 __attribute__ ((__pure__)); 145 operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT; 146 #endif 147 148 #if __cplusplus >= 201103L 149 explicit operator bool() const 150 { return _M_exception_object; } 151 #endif 152 153 friend bool 154 operator==(const exception_ptr&, const exception_ptr&) 155 _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 156 157 const class std::type_info* 158 __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT 159 __attribute__ ((__pure__)); 160 }; 161 162 /// @relates exception_ptr @{ 163 164 bool 165 operator==(const exception_ptr&, const exception_ptr&) 166 _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 167 168 bool 169 operator!=(const exception_ptr&, const exception_ptr&) 170 _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); 171 172 inline void 173 swap(exception_ptr& __lhs, exception_ptr& __rhs) 174 { __lhs.swap(__rhs); } 175 176 // @} 177 178 /// @cond undocumented 179 template<typename _Ex> 180 inline void 181 __dest_thunk(void* __x) 182 { static_cast<_Ex*>(__x)->~_Ex(); } 183 /// @endcond 184 185 } // namespace __exception_ptr 186 187 /// Obtain an exception_ptr pointing to a copy of the supplied object. 188 template<typename _Ex> 189 exception_ptr 190 make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT 191 { 192 #if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI \ 193 && __cplusplus >= 201103L 194 using _Ex2 = typename remove_reference<_Ex>::type; 195 void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); 196 (void) __cxxabiv1::__cxa_init_primary_exception( 197 __e, const_cast<std::type_info*>(&typeid(_Ex)), 198 __exception_ptr::__dest_thunk<_Ex2>); 199 try 200 { 201 ::new (__e) _Ex2(std::forward<_Ex>(__ex)); 202 return exception_ptr(__e); 203 } 204 catch(...) 205 { 206 __cxxabiv1::__cxa_free_exception(__e); 207 return current_exception(); 208 } 209 #elif __cpp_exceptions 210 try 211 { 212 throw __ex; 213 } 214 catch(...) 215 { 216 return current_exception(); 217 } 218 #else // no RTTI and no exceptions 219 return exception_ptr(); 220 #endif 221 } 222 223 /// @} group exceptions 224 } // namespace std 225 226 } // extern "C++" 227 228 #pragma GCC visibility pop 229 230 #endif 231