exception_ptr.h 7.3 KB

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