blob: ec8969aaf4c01aba1cb7938e821bdf1eefa9bc8a [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 Fiselierb0da5fa2017-01-03 01:18:48 +000015#if defined(__APPLE__) && !defined(LIBCXXRT) && \
16 !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000017 #include <cxxabi.h>
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000018
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000019 using namespace __cxxabiv1;
David Chisnall1d581062011-09-21 08:39:44 +000020 #define HAVE_DEPENDENT_EH_ABI 1
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000021 #ifndef _LIBCPPABI_VERSION
22 using namespace __cxxabiapple;
23 // On Darwin, there are two STL shared libraries and a lower level ABI
Marshall Clowf98383c2013-11-11 23:27:19 +000024 // shared library. The globals holding the current terminate handler and
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000025 // current unexpected handler are in the ABI library.
26 #define __terminate_handler __cxxabiapple::__cxa_terminate_handler
27 #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
28 #endif // _LIBCPPABI_VERSION
Benjamin Krameraf9fc2c2015-10-16 11:14:30 +000029#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)
David Chisnall1d581062011-09-21 08:39:44 +000030 #include <cxxabi.h>
31 using namespace __cxxabiv1;
Richard Smithffd74672012-07-11 09:35:47 +000032 #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
33 #define HAVE_DEPENDENT_EH_ABI 1
34 #endif
Benjamin Krameraf9fc2c2015-10-16 11:14:30 +000035#elif !defined(__GLIBCXX__) // defined(LIBCXX_BUILDING_LIBCXXABI)
Eric Fiselier637dd952016-09-28 22:08:13 +000036 _LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler;
37 _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler;
Benjamin Krameraf9fc2c2015-10-16 11:14:30 +000038#endif // defined(LIBCXX_BUILDING_LIBCXXABI)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000039
David Chisnall3954f442012-02-29 12:59:17 +000040namespace std
41{
42
Michael J. Spencer7deadc82012-11-30 21:02:29 +000043#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
Howard Hinnant4ad4eee2012-02-02 20:48:35 +000044
David Chisnall1d581062011-09-21 08:39:44 +000045// libcxxrt provides implementations of these functions itself.
David Chisnall3954f442012-02-29 12:59:17 +000046unexpected_handler
47set_unexpected(unexpected_handler func) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000048{
Howard Hinnante65e8e32010-12-02 16:45:21 +000049 return __sync_lock_test_and_set(&__unexpected_handler, func);
50}
51
David Chisnall3954f442012-02-29 12:59:17 +000052unexpected_handler
53get_unexpected() _NOEXCEPT
Howard Hinnante65e8e32010-12-02 16:45:21 +000054{
David Chisnall3954f442012-02-29 12:59:17 +000055 return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000056}
57
Richard Smithcabd3922012-07-26 02:04:22 +000058_LIBCPP_NORETURN
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000059void
David Chisnall3954f442012-02-29 12:59:17 +000060unexpected()
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000061{
David Chisnall3954f442012-02-29 12:59:17 +000062 (*get_unexpected())();
Howard Hinnant34468d42010-08-22 13:53:14 +000063 // unexpected handler should not return
David Chisnall3954f442012-02-29 12:59:17 +000064 terminate();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000065}
66
David Chisnall3954f442012-02-29 12:59:17 +000067terminate_handler
68set_terminate(terminate_handler func) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000069{
Howard Hinnante65e8e32010-12-02 16:45:21 +000070 return __sync_lock_test_and_set(&__terminate_handler, func);
71}
72
David Chisnall3954f442012-02-29 12:59:17 +000073terminate_handler
74get_terminate() _NOEXCEPT
Howard Hinnante65e8e32010-12-02 16:45:21 +000075{
David Chisnall3954f442012-02-29 12:59:17 +000076 return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000077}
78
Marshall Cloweae03f62013-11-19 18:05:03 +000079#ifndef __EMSCRIPTEN__ // We provide this in JS
Richard Smithcabd3922012-07-26 02:04:22 +000080_LIBCPP_NORETURN
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000081void
David Chisnall3954f442012-02-29 12:59:17 +000082terminate() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000083{
Howard Hinnant72f73582010-08-11 17:04:31 +000084#ifndef _LIBCPP_NO_EXCEPTIONS
85 try
86 {
Howard Hinnantffb308e2010-08-22 00:03:27 +000087#endif // _LIBCPP_NO_EXCEPTIONS
David Chisnall3954f442012-02-29 12:59:17 +000088 (*get_terminate())();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000089 // handler should not return
Ed Schouten7a441452015-03-10 07:57:43 +000090 fprintf(stderr, "terminate_handler unexpectedly returned\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +000091 ::abort();
Howard Hinnant72f73582010-08-11 17:04:31 +000092#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantffb308e2010-08-22 00:03:27 +000093 }
Howard Hinnant72f73582010-08-11 17:04:31 +000094 catch (...)
95 {
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000096 // handler should not throw exception
Ed Schouten7a441452015-03-10 07:57:43 +000097 fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +000098 ::abort();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +000099 }
Howard Hinnantffb308e2010-08-22 00:03:27 +0000100#endif // _LIBCPP_NO_EXCEPTIONS
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000101}
Marshall Cloweae03f62013-11-19 18:05:03 +0000102#endif // !__EMSCRIPTEN__
Howard Hinnant4ad4eee2012-02-02 20:48:35 +0000103#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000104
Marshall Clowe6a76af2015-06-02 22:25:23 +0000105#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)
Marshall Clow209dacc2015-06-02 15:33:38 +0000106bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
107
Marshall Clow209dacc2015-06-02 15:33:38 +0000108int uncaught_exceptions() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000109{
Eric Fiselierb0da5fa2017-01-03 01:18:48 +0000110#if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \
111 (defined(__APPLE__) || defined(_LIBCPPABI_VERSION))
Marshall Clow209dacc2015-06-02 15:33:38 +0000112 // on Darwin, there is a helper function so __cxa_get_globals is private
113# if _LIBCPPABI_VERSION > 1101
114 return __cxa_uncaught_exceptions();
115# else
116 return __cxa_uncaught_exception() ? 1 : 0;
117# endif
Howard Hinnant3472f5b2012-02-29 15:37:30 +0000118#else // __APPLE__
Howard Hinnant408927e2013-10-04 21:14:44 +0000119# if defined(_MSC_VER) && ! defined(__clang__)
Marshall Clow209dacc2015-06-02 15:33:38 +0000120 _LIBCPP_WARNING("uncaught_exceptions not yet implemented")
Howard Hinnant408927e2013-10-04 21:14:44 +0000121# else
122# warning uncaught_exception not yet implemented
123# endif
Marshall Clow209dacc2015-06-02 15:33:38 +0000124 fprintf(stderr, "uncaught_exceptions not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000125 ::abort();
Howard Hinnantffb308e2010-08-22 00:03:27 +0000126#endif // __APPLE__
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000127}
128
Howard Hinnant408927e2013-10-04 21:14:44 +0000129
Howard Hinnant4ad4eee2012-02-02 20:48:35 +0000130#ifndef _LIBCPPABI_VERSION
131
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000132exception::~exception() _NOEXCEPT
Howard Hinnantffb308e2010-08-22 00:03:27 +0000133{
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000134}
135
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000136const char* exception::what() const _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000137{
138 return "std::exception";
139}
140
David Chisnallba252b82012-03-14 14:11:13 +0000141#endif // _LIBCPPABI_VERSION
142#endif //LIBCXXRT
Michael J. Spencer7deadc82012-11-30 21:02:29 +0000143#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
David Chisnallba252b82012-03-14 14:11:13 +0000144
145bad_exception::~bad_exception() _NOEXCEPT
146{
147}
148
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000149const char* bad_exception::what() const _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000150{
151 return "std::bad_exception";
152}
153
David Chisnallba252b82012-03-14 14:11:13 +0000154#endif
155
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000156#if defined(__GLIBCXX__)
157
158// libsupc++ does not implement the dependent EH ABI and the functionality
159// it uses to implement std::exception_ptr (which it declares as an alias of
160// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
161// we have little choice but to hijack std::__exception_ptr::exception_ptr's
162// (which fortunately has the same layout as our std::exception_ptr) copy
163// constructor, assignment operator and destructor (which are part of its
164// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
165// function.
166
167namespace __exception_ptr
168{
169
170struct exception_ptr
171{
172 void* __ptr_;
173
174 exception_ptr(const exception_ptr&) _NOEXCEPT;
175 exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
176 ~exception_ptr() _NOEXCEPT;
177};
178
179}
180
181_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
182
183#endif
Howard Hinnant4ad4eee2012-02-02 20:48:35 +0000184
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000185exception_ptr::~exception_ptr() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000186{
David Chisnall1d581062011-09-21 08:39:44 +0000187#if HAVE_DEPENDENT_EH_ABI
188 __cxa_decrement_exception_refcount(__ptr_);
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000189#elif defined(__GLIBCXX__)
190 reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000191#else
Howard Hinnant408927e2013-10-04 21:14:44 +0000192# if defined(_MSC_VER) && ! defined(__clang__)
193 _LIBCPP_WARNING("exception_ptr not yet implemented")
194# else
195# warning exception_ptr not yet implemented
196# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000197 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000198 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000199#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000200}
201
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000202exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000203 : __ptr_(other.__ptr_)
204{
David Chisnall1d581062011-09-21 08:39:44 +0000205#if HAVE_DEPENDENT_EH_ABI
206 __cxa_increment_exception_refcount(__ptr_);
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000207#elif defined(__GLIBCXX__)
208 new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
209 reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000210#else
Howard Hinnant408927e2013-10-04 21:14:44 +0000211# if defined(_MSC_VER) && ! defined(__clang__)
212 _LIBCPP_WARNING("exception_ptr not yet implemented")
213# else
214# warning exception_ptr not yet implemented
215# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000216 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000217 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000218#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000219}
220
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000221exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000222{
David Chisnall1d581062011-09-21 08:39:44 +0000223#if HAVE_DEPENDENT_EH_ABI
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000224 if (__ptr_ != other.__ptr_)
225 {
David Chisnall1d581062011-09-21 08:39:44 +0000226 __cxa_increment_exception_refcount(other.__ptr_);
227 __cxa_decrement_exception_refcount(__ptr_);
Howard Hinnant34468d42010-08-22 13:53:14 +0000228 __ptr_ = other.__ptr_;
229 }
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000230 return *this;
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000231#elif defined(__GLIBCXX__)
232 *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
233 reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
234 return *this;
235#else
Howard Hinnant408927e2013-10-04 21:14:44 +0000236# if defined(_MSC_VER) && ! defined(__clang__)
237 _LIBCPP_WARNING("exception_ptr not yet implemented")
238# else
239# warning exception_ptr not yet implemented
240# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000241 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000242 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000243#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000244}
245
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000246nested_exception::nested_exception() _NOEXCEPT
Howard Hinnante4f92722010-05-27 17:06:52 +0000247 : __ptr_(current_exception())
248{
249}
250
Peter Collingbournedc009952013-10-06 22:13:16 +0000251#if !defined(__GLIBCXX__)
252
Howard Hinnant1bc52cf2011-05-26 18:23:59 +0000253nested_exception::~nested_exception() _NOEXCEPT
Howard Hinnante4f92722010-05-27 17:06:52 +0000254{
255}
256
Peter Collingbournedc009952013-10-06 22:13:16 +0000257#endif
258
Richard Smithcabd3922012-07-26 02:04:22 +0000259_LIBCPP_NORETURN
Howard Hinnante4f92722010-05-27 17:06:52 +0000260void
Howard Hinnant8df96292011-05-26 17:07:32 +0000261nested_exception::rethrow_nested() const
Howard Hinnante4f92722010-05-27 17:06:52 +0000262{
263 if (__ptr_ == nullptr)
264 terminate();
265 rethrow_exception(__ptr_);
266}
267
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000268#if !defined(__GLIBCXX__)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000269
David Chisnall3954f442012-02-29 12:59:17 +0000270exception_ptr current_exception() _NOEXCEPT
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000271{
David Chisnall1d581062011-09-21 08:39:44 +0000272#if HAVE_DEPENDENT_EH_ABI
Howard Hinnant34468d42010-08-22 13:53:14 +0000273 // be nicer if there was a constructor that took a ptr, then
274 // this whole function would be just:
275 // return exception_ptr(__cxa_current_primary_exception());
David Chisnall3954f442012-02-29 12:59:17 +0000276 exception_ptr ptr;
David Chisnall1d581062011-09-21 08:39:44 +0000277 ptr.__ptr_ = __cxa_current_primary_exception();
Howard Hinnant34468d42010-08-22 13:53:14 +0000278 return ptr;
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000279#else
Howard Hinnant408927e2013-10-04 21:14:44 +0000280# if defined(_MSC_VER) && ! defined(__clang__)
281 _LIBCPP_WARNING( "exception_ptr not yet implemented" )
282# else
283# warning exception_ptr not yet implemented
284# endif
Ed Schouten7a441452015-03-10 07:57:43 +0000285 fprintf(stderr, "exception_ptr not yet implemented\n");
Peter Collingbourne5f845a72013-10-06 22:13:24 +0000286 ::abort();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000287#endif
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000288}
289
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000290#endif // !__GLIBCXX__
291
Richard Smithcabd3922012-07-26 02:04:22 +0000292_LIBCPP_NORETURN
David Chisnall3954f442012-02-29 12:59:17 +0000293void rethrow_exception(exception_ptr p)
Nick Kledzikd1a61bb2010-05-14 20:19:37 +0000294{
David Chisnall1d581062011-09-21 08:39:44 +0000295#if HAVE_DEPENDENT_EH_ABI
296 __cxa_rethrow_primary_exception(p.__ptr_);
Howard Hinnant34468d42010-08-22 13:53:14 +0000297 // if p.__ptr_ is NULL, above returns so we terminate
Howard Hinnantffb308e2010-08-22 00:03:27 +0000298 terminate();
Peter Collingbourne4d7da9a2013-10-06 22:13:21 +0000299#elif defined(__GLIBCXX__)
300 rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
301#else
Howard Hinnant408927e2013-10-04 21:14:44 +0000302# if defined(_MSC_VER) && ! defined(__clang__)
303 _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}
David Chisnall3954f442012-02-29 12:59:17 +0000311} // std