blob: 35a3a9abaeb136a3aa8089f4e88770b1b3781053 [file] [log] [blame]
Nick Kledzikd1a61bb2010-05-14 20:19:37 +00001//===------------------------ exception.cpp -------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantee11c312010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Nick Kledzikd1a61bb2010-05-14 20:19:37 +00007//
8//===----------------------------------------------------------------------===//
9#include <stdlib.h>
Howard Hinnant84f697e2013-07-23 16:05:56 +000010#include <stdio.h>
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000011
12#include "exception"
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +000013#include "new"
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000014
Eric Fiselier2391b382017-01-07 10:04:40 +000015#if defined(_LIBCPP_ABI_MICROSOFT)
16#include <eh.h>
17#include <corecrt_terminate.h>
18#elif defined(__APPLE__) && !defined(LIBCXXRT) && \
Eric Fiselierb0da5fa2017-01-03 01:18:48 +000019 !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000020 #include <cxxabi.h>
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000021
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000022 using namespace __cxxabiv1;
David Chisnall1d581062011-09-21 08:39:44 +000023 #define HAVE_DEPENDENT_EH_ABI 1
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000024 #ifndef _LIBCPPABI_VERSION
25 using namespace __cxxabiapple;
26 // On Darwin, there are two STL shared libraries and a lower level ABI
Marshall Clowf98383c2013-11-11 23:27:19 +000027 // shared library. The globals holding the current terminate handler and
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000028 // current unexpected handler are in the ABI library.
29 #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
30 #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
31 #endif // _LIBCPPABI_VERSION
Benjamin Krameraf9fc2c2015-10-16 11:14:30 +000032#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
David Chisnall1d581062011-09-21 08:39:44 +000033 #include <cxxabi.h>
34 using namespace __cxxabiv1;
Richard Smithffd74672012-07-11 09:35:47 +000035 #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
36 #define HAVE_DEPENDENT_EH_ABI 1
37 #endif
Benjamin Krameraf9fc2c2015-10-16 11:14:30 +000038#elif !defined(__GLIBCXX__) // defined(LIBCXX_BUILDING_LIBCXXABI)
Eric Fiselier637dd952016-09-28 22:08:13 +000039 _LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler;
40 _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
Benjamin Krameraf9fc2c2015-10-16 11:14:30 +000041#endif // defined(LIBCXX_BUILDING_LIBCXXABI)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000042
David Chisnall3954f442012-02-29 12:59:17 +000043namespace std
44{
45
Michael J. Spencer7deadc82012-11-30 21:02:29 +000046#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000047
David Chisnall1d581062011-09-21 08:39:44 +000048// libcxxrt provides implementations of these functions itself.
David Chisnall3954f442012-02-29 12:59:17 +000049unexpected_handler
50set_unexpected(unexpected_handler func) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000051{
Eric Fiselier2391b382017-01-07 10:04:40 +000052#if defined(_LIBCPP_ABI_MICROSOFT)
53 return ::set_unexpected(func);
54#else
55 return __sync_lock_test_and_set(&__unexpected_handler, func);
56#endif
Howard Hinnante65e8e32010-12-02 16:45:21 +000057}
58
David Chisnall3954f442012-02-29 12:59:17 +000059unexpected_handler
60get_unexpected() _NOEXCEPT
Howard Hinnante65e8e32010-12-02 16:45:21 +000061{
Eric Fiselier2391b382017-01-07 10:04:40 +000062#if defined(_LIBCPP_ABI_MICROSOFT)
63 return ::_get_unexpected();
64#else
65 return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
66#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000067}
68
Richard Smithcabd3922012-07-26 02:04:22 +000069_LIBCPP_NORETURN
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000070void
David Chisnall3954f442012-02-29 12:59:17 +000071unexpected()
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000072{
David Chisnall3954f442012-02-29 12:59:17 +000073 (*get_unexpected())();
Howard Hinnant34468d42010-08-22 13:53:14 +000074 // unexpected handler should not return
David Chisnall3954f442012-02-29 12:59:17 +000075 terminate();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000076}
77
David Chisnall3954f442012-02-29 12:59:17 +000078terminate_handler
79set_terminate(terminate_handler func) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000080{
Eric Fiselier2391b382017-01-07 10:04:40 +000081#if defined(_LIBCPP_ABI_MICROSOFT)
82 return ::set_terminate(func);
83#else
84 return __sync_lock_test_and_set(&__terminate_handler, func);
85#endif
Howard Hinnante65e8e32010-12-02 16:45:21 +000086}
87
David Chisnall3954f442012-02-29 12:59:17 +000088terminate_handler
89get_terminate() _NOEXCEPT
Howard Hinnante65e8e32010-12-02 16:45:21 +000090{
Eric Fiselier2391b382017-01-07 10:04:40 +000091#if defined(_LIBCPP_ABI_MICROSOFT)
92 return ::_get_terminate();
93#else
94 return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
95#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000096}
97
Marshall Cloweae03f62013-11-19 18:05:03 +000098#ifndef __EMSCRIPTEN__ // We provide this in JS
Richard Smithcabd3922012-07-26 02:04:22 +000099_LIBCPP_NORETURN
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000100void
David Chisnall3954f442012-02-29 12:59:17 +0000101terminate() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000102{
Howard Hinnant72f73582010-08-11 17:04:31 +0000103#ifndef _LIBCPP_NO_EXCEPTIONS
104 try
105 {
Howard Hinnantffb308e2010-08-22 00:03:27 +0000106#endif // _LIBCPP_NO_EXCEPTIONS
David Chisnall3954f442012-02-29 12:59:17 +0000107 (*get_terminate())();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000108 // handler should not return
Ed Schouten7a441452015-03-10 07:57:43 +0000109 fprintf(stderr, "terminate_handler unexpectedly returned\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000110 ::abort();
Howard Hinnant72f73582010-08-11 17:04:31 +0000111#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantffb308e2010-08-22 00:03:27 +0000112 }
Howard Hinnant72f73582010-08-11 17:04:31 +0000113 catch (...)
114 {
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000115 // handler should not throw exception
Ed Schouten7a441452015-03-10 07:57:43 +0000116 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000117 ::abort();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000118 }
Howard Hinnantffb308e2010-08-22 00:03:27 +0000119#endif // _LIBCPP_NO_EXCEPTIONS
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000120}
Marshall Cloweae03f62013-11-19 18:05:03 +0000121#endif // !__EMSCRIPTEN__
Howard Hinnant4ad4eee2012-02-02 20:48:35 +0000122#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000123
Marshall Clowe6a76af2015-06-02 22:25:23 +0000124#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)
Eric Fiselier2391b382017-01-07 10:04:40 +0000125
Marshall Clow209dacc2015-06-02 15:33:38 +0000126bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
127
Marshall Clow209dacc2015-06-02 15:33:38 +0000128int uncaught_exceptions() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000129{
Eric Fiselierb0da5fa2017-01-03 01:18:48 +0000130#if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \
131 (defined(__APPLE__) || defined(_LIBCPPABI_VERSION))
Marshall Clow209dacc2015-06-02 15:33:38 +0000132 // on Darwin, there is a helper function so __cxa_get_globals is private
133# if _LIBCPPABI_VERSION > 1101
134 return __cxa_uncaught_exceptions();
135# else
136 return __cxa_uncaught_exception() ? 1 : 0;
137# endif
Eric Fiselier2391b382017-01-07 10:04:40 +0000138#elif defined(_LIBCPP_ABI_MICROSOFT)
139 return __uncaught_exceptions();
140#else
Saleem Abdulrasoold94ab1c2017-02-06 05:26:49 +0000141# if defined(_LIBCPP_MSVC)
Marshall Clow209dacc2015-06-02 15:33:38 +0000142 _LIBCPP_WARNING("uncaught_exceptions not yet implemented")
Howard Hinnant408927e2013-10-04 21:14:44 +0000143# else
144# warning uncaught_exception not yet implemented
145# endif
Marshall Clow209dacc2015-06-02 15:33:38 +0000146 fprintf(stderr, "uncaught_exceptions not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000147 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000148#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000149}
150
Howard Hinnant408927e2013-10-04 21:14:44 +0000151
Howard Hinnant4ad4eee2012-02-02 20:48:35 +0000152#ifndef _LIBCPPABI_VERSION
153
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000154exception::~exception() _NOEXCEPT
Howard Hinnantffb308e2010-08-22 00:03:27 +0000155{
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000156}
157
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000158const char* exception::what() const _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000159{
160 return "std::exception";
161}
162
David Chisnallba252b82012-03-14 14:11:13 +0000163#endif // _LIBCPPABI_VERSION
164#endif //LIBCXXRT
Michael J. Spencer7deadc82012-11-30 21:02:29 +0000165#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
David Chisnallba252b82012-03-14 14:11:13 +0000166
167bad_exception::~bad_exception() _NOEXCEPT
168{
169}
170
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000171const char* bad_exception::what() const _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000172{
173 return "std::bad_exception";
174}
175
David Chisnallba252b82012-03-14 14:11:13 +0000176#endif
177
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000178#if defined(__GLIBCXX__)
179
180// libsupc++ does not implement the dependent EH ABI and the functionality
181// it uses to implement std::exception_ptr (which it declares as an alias of
182// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
183// we have little choice but to hijack std::__exception_ptr::exception_ptr's
184// (which fortunately has the same layout as our std::exception_ptr) copy
185// constructor, assignment operator and destructor (which are part of its
186// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
187// function.
188
189namespace __exception_ptr
190{
191
192struct exception_ptr
193{
194 void* __ptr_;
195
196 exception_ptr(const exception_ptr&) _NOEXCEPT;
197 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
198 ~exception_ptr() _NOEXCEPT;
199};
200
201}
202
203_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
204
205#endif
Howard Hinnant4ad4eee2012-02-02 20:48:35 +0000206
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000207exception_ptr::~exception_ptr() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000208{
David Chisnall1d581062011-09-21 08:39:44 +0000209#if HAVE_DEPENDENT_EH_ABI
210 __cxa_decrement_exception_refcount(__ptr_);
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000211#elif defined(__GLIBCXX__)
212 reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000213#else
Saleem Abdulrasoold94ab1c2017-02-06 05:26:49 +0000214# if defined(_LIBCPP_MSVC)
Howard Hinnant408927e2013-10-04 21:14:44 +0000215 _LIBCPP_WARNING("exception_ptr not yet implemented")
216# else
217# warning exception_ptr not yet implemented
218# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000219 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000220 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000221#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000222}
223
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000224exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000225 : __ptr_(other.__ptr_)
226{
David Chisnall1d581062011-09-21 08:39:44 +0000227#if HAVE_DEPENDENT_EH_ABI
228 __cxa_increment_exception_refcount(__ptr_);
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000229#elif defined(__GLIBCXX__)
230 new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
231 reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000232#else
Saleem Abdulrasoold94ab1c2017-02-06 05:26:49 +0000233# if defined(_LIBCPP_MSVC)
Howard Hinnant408927e2013-10-04 21:14:44 +0000234 _LIBCPP_WARNING("exception_ptr not yet implemented")
235# else
236# warning exception_ptr not yet implemented
237# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000238 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000239 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000240#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000241}
242
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000243exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000244{
David Chisnall1d581062011-09-21 08:39:44 +0000245#if HAVE_DEPENDENT_EH_ABI
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000246 if (__ptr_ != other.__ptr_)
247 {
David Chisnall1d581062011-09-21 08:39:44 +0000248 __cxa_increment_exception_refcount(other.__ptr_);
249 __cxa_decrement_exception_refcount(__ptr_);
Howard Hinnant34468d42010-08-22 13:53:14 +0000250 __ptr_ = other.__ptr_;
251 }
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000252 return *this;
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000253#elif defined(__GLIBCXX__)
254 *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
255 reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
256 return *this;
257#else
Saleem Abdulrasoold94ab1c2017-02-06 05:26:49 +0000258# if defined(_LIBCPP_MSVC)
Howard Hinnant408927e2013-10-04 21:14:44 +0000259 _LIBCPP_WARNING("exception_ptr not yet implemented")
260# else
261# warning exception_ptr not yet implemented
262# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000263 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000264 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000265#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000266}
267
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000268nested_exception::nested_exception() _NOEXCEPT
Howard Hinnante4f92722010-05-27 17:06:52 +0000269 : __ptr_(current_exception())
270{
271}
272
Peter Collingbournedc009952013-10-06 22:13:16 +0000273#if !defined(__GLIBCXX__)
274
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000275nested_exception::~nested_exception() _NOEXCEPT
Howard Hinnante4f92722010-05-27 17:06:52 +0000276{
277}
278
Peter Collingbournedc009952013-10-06 22:13:16 +0000279#endif
280
Richard Smithcabd3922012-07-26 02:04:22 +0000281_LIBCPP_NORETURN
Howard Hinnante4f92722010-05-27 17:06:52 +0000282void
Howard Hinnant8df96292011-05-26 17:07:32 +0000283nested_exception::rethrow_nested() const
Howard Hinnante4f92722010-05-27 17:06:52 +0000284{
285 if (__ptr_ == nullptr)
286 terminate();
287 rethrow_exception(__ptr_);
288}
289
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000290#if !defined(__GLIBCXX__)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000291
David Chisnall3954f442012-02-29 12:59:17 +0000292exception_ptr current_exception() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000293{
David Chisnall1d581062011-09-21 08:39:44 +0000294#if HAVE_DEPENDENT_EH_ABI
Howard Hinnant34468d42010-08-22 13:53:14 +0000295 // be nicer if there was a constructor that took a ptr, then
296 // this whole function would be just:
297 // return exception_ptr(__cxa_current_primary_exception());
David Chisnall3954f442012-02-29 12:59:17 +0000298 exception_ptr ptr;
David Chisnall1d581062011-09-21 08:39:44 +0000299 ptr.__ptr_ = __cxa_current_primary_exception();
Howard Hinnant34468d42010-08-22 13:53:14 +0000300 return ptr;
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000301#else
Saleem Abdulrasoold94ab1c2017-02-06 05:26:49 +0000302# if defined(_LIBCPP_MSVC)
Howard Hinnant408927e2013-10-04 21:14:44 +0000303 _LIBCPP_WARNING( "exception_ptr not yet implemented" )
304# else
305# warning exception_ptr not yet implemented
306# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000307 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000308 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000309#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000310}
311
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000312#endif // !__GLIBCXX__
313
Richard Smithcabd3922012-07-26 02:04:22 +0000314_LIBCPP_NORETURN
David Chisnall3954f442012-02-29 12:59:17 +0000315void rethrow_exception(exception_ptr p)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000316{
David Chisnall1d581062011-09-21 08:39:44 +0000317#if HAVE_DEPENDENT_EH_ABI
318 __cxa_rethrow_primary_exception(p.__ptr_);
Howard Hinnant34468d42010-08-22 13:53:14 +0000319 // if p.__ptr_ is NULL, above returns so we terminate
Howard Hinnantffb308e2010-08-22 00:03:27 +0000320 terminate();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000321#elif defined(__GLIBCXX__)
322 rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
323#else
Saleem Abdulrasoold94ab1c2017-02-06 05:26:49 +0000324# if defined(_LIBCPP_MSVC)
Howard Hinnant408927e2013-10-04 21:14:44 +0000325 _LIBCPP_WARNING("exception_ptr not yet implemented")
326# else
327# warning exception_ptr not yet implemented
328# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000329 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000330 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000331#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000332}
David Chisnall3954f442012-02-29 12:59:17 +0000333} // std