xref: /openbsd-src/gnu/llvm/libcxx/include/exception (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_EXCEPTION
1146035553Spatrick#define _LIBCPP_EXCEPTION
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    exception synopsis
1546035553Spatrick
1646035553Spatricknamespace std
1746035553Spatrick{
1846035553Spatrick
1946035553Spatrickclass exception
2046035553Spatrick{
2146035553Spatrickpublic:
2246035553Spatrick    exception() noexcept;
2346035553Spatrick    exception(const exception&) noexcept;
2446035553Spatrick    exception& operator=(const exception&) noexcept;
2546035553Spatrick    virtual ~exception() noexcept;
2646035553Spatrick    virtual const char* what() const noexcept;
2746035553Spatrick};
2846035553Spatrick
2946035553Spatrickclass bad_exception
3046035553Spatrick    : public exception
3146035553Spatrick{
3246035553Spatrickpublic:
3346035553Spatrick    bad_exception() noexcept;
3446035553Spatrick    bad_exception(const bad_exception&) noexcept;
3546035553Spatrick    bad_exception& operator=(const bad_exception&) noexcept;
3646035553Spatrick    virtual ~bad_exception() noexcept;
3746035553Spatrick    virtual const char* what() const noexcept;
3846035553Spatrick};
3946035553Spatrick
4046035553Spatricktypedef void (*unexpected_handler)();
4146035553Spatrickunexpected_handler set_unexpected(unexpected_handler  f ) noexcept;
4246035553Spatrickunexpected_handler get_unexpected() noexcept;
4346035553Spatrick[[noreturn]] void unexpected();
4446035553Spatrick
4546035553Spatricktypedef void (*terminate_handler)();
4646035553Spatrickterminate_handler set_terminate(terminate_handler  f ) noexcept;
4746035553Spatrickterminate_handler get_terminate() noexcept;
4846035553Spatrick[[noreturn]] void terminate() noexcept;
4946035553Spatrick
5046035553Spatrickbool uncaught_exception()  noexcept;
5146035553Spatrickint  uncaught_exceptions() noexcept;  // C++17
5246035553Spatrick
5346035553Spatricktypedef unspecified exception_ptr;
5446035553Spatrick
5546035553Spatrickexception_ptr current_exception() noexcept;
5646035553Spatrickvoid rethrow_exception [[noreturn]] (exception_ptr p);
5746035553Spatricktemplate<class E> exception_ptr make_exception_ptr(E e) noexcept;
5846035553Spatrick
5946035553Spatrickclass nested_exception
6046035553Spatrick{
6146035553Spatrickpublic:
6246035553Spatrick    nested_exception() noexcept;
6346035553Spatrick    nested_exception(const nested_exception&) noexcept = default;
6446035553Spatrick    nested_exception& operator=(const nested_exception&) noexcept = default;
6546035553Spatrick    virtual ~nested_exception() = default;
6646035553Spatrick
6746035553Spatrick    // access functions
6846035553Spatrick    [[noreturn]] void rethrow_nested() const;
6946035553Spatrick    exception_ptr nested_ptr() const noexcept;
7046035553Spatrick};
7146035553Spatrick
7246035553Spatricktemplate <class T> [[noreturn]] void throw_with_nested(T&& t);
7346035553Spatricktemplate <class E> void rethrow_if_nested(const E& e);
7446035553Spatrick
7546035553Spatrick}  // std
7646035553Spatrick
7746035553Spatrick*/
7846035553Spatrick
79*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
8076d0caaeSpatrick#include <__availability>
8146035553Spatrick#include <__config>
8276d0caaeSpatrick#include <__memory/addressof.h>
83*4bdff4beSrobert#include <__type_traits/decay.h>
84*4bdff4beSrobert#include <__type_traits/is_base_of.h>
85*4bdff4beSrobert#include <__type_traits/is_class.h>
86*4bdff4beSrobert#include <__type_traits/is_convertible.h>
87*4bdff4beSrobert#include <__type_traits/is_copy_constructible.h>
88*4bdff4beSrobert#include <__type_traits/is_final.h>
89*4bdff4beSrobert#include <__type_traits/is_polymorphic.h>
9046035553Spatrick#include <cstddef>
9146035553Spatrick#include <cstdlib>
9246035553Spatrick#include <version>
9346035553Spatrick
94*4bdff4beSrobert// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
95*4bdff4beSrobert// which we use in order to be ABI-compatible with other STLs on Windows.
9646035553Spatrick#if defined(_LIBCPP_ABI_VCRUNTIME)
9746035553Spatrick#  include <vcruntime_exception.h>
9846035553Spatrick#endif
9946035553Spatrick
10046035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
10146035553Spatrick#  pragma GCC system_header
10246035553Spatrick#endif
10346035553Spatrick
10446035553Spatricknamespace std  // purposefully not using versioning namespace
10546035553Spatrick{
10646035553Spatrick
107*4bdff4beSrobert#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
108*4bdff4beSrobert// The std::exception class was already included above, but we're explicit about this condition here for clarity.
109*4bdff4beSrobert
110*4bdff4beSrobert#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
111*4bdff4beSrobert// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
112*4bdff4beSrobert// when _HAS_EXCEPTIONS == 0.
113*4bdff4beSrobert//
114*4bdff4beSrobert// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
115*4bdff4beSrobert// (after all those are simply types like any other), we define an ABI-compatible version
116*4bdff4beSrobert// of the VCRuntime std::exception and std::bad_exception types in that mode.
117*4bdff4beSrobert
118*4bdff4beSrobertstruct __std_exception_data {
119*4bdff4beSrobert  char const* _What;
120*4bdff4beSrobert  bool _DoFree;
121*4bdff4beSrobert};
122*4bdff4beSrobert
123*4bdff4beSrobertclass exception { // base of all library exceptions
124*4bdff4beSrobertpublic:
125*4bdff4beSrobert  exception() _NOEXCEPT : __data_() {}
126*4bdff4beSrobert
127*4bdff4beSrobert  explicit exception(char const* __message) _NOEXCEPT : __data_() {
128*4bdff4beSrobert    __data_._What = __message;
129*4bdff4beSrobert    __data_._DoFree = true;
130*4bdff4beSrobert  }
131*4bdff4beSrobert
132*4bdff4beSrobert  exception(exception const&) _NOEXCEPT {}
133*4bdff4beSrobert
134*4bdff4beSrobert  exception& operator=(exception const&) _NOEXCEPT { return *this; }
135*4bdff4beSrobert
136*4bdff4beSrobert  virtual ~exception() _NOEXCEPT {}
137*4bdff4beSrobert
138*4bdff4beSrobert  virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
139*4bdff4beSrobert
140*4bdff4beSrobertprivate:
141*4bdff4beSrobert  __std_exception_data __data_;
142*4bdff4beSrobert};
143*4bdff4beSrobert
144*4bdff4beSrobertclass bad_exception : public exception {
145*4bdff4beSrobertpublic:
146*4bdff4beSrobert  bad_exception() _NOEXCEPT : exception("bad exception") {}
147*4bdff4beSrobert};
148*4bdff4beSrobert
149*4bdff4beSrobert#else // !defined(_LIBCPP_ABI_VCRUNTIME)
150*4bdff4beSrobert// On all other platforms, we define our own std::exception and std::bad_exception types
151*4bdff4beSrobert// regardless of whether exceptions are turned on as a language feature.
152*4bdff4beSrobert
153*4bdff4beSrobertclass _LIBCPP_EXCEPTION_ABI exception {
15446035553Spatrickpublic:
15546035553Spatrick  _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
156037e7968Spatrick  _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default;
157037e7968Spatrick
15846035553Spatrick  virtual ~exception() _NOEXCEPT;
15946035553Spatrick  virtual const char* what() const _NOEXCEPT;
16046035553Spatrick};
16146035553Spatrick
162*4bdff4beSrobertclass _LIBCPP_EXCEPTION_ABI bad_exception : public exception {
16346035553Spatrickpublic:
16446035553Spatrick  _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}
165*4bdff4beSrobert  ~bad_exception() _NOEXCEPT override;
166*4bdff4beSrobert  const char* what() const _NOEXCEPT override;
16746035553Spatrick};
16846035553Spatrick#endif // !_LIBCPP_ABI_VCRUNTIME
16946035553Spatrick
17046035553Spatrick#if _LIBCPP_STD_VER <= 14 \
17146035553Spatrick    || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \
17246035553Spatrick    || defined(_LIBCPP_BUILDING_LIBRARY)
17346035553Spatricktypedef void (*unexpected_handler)();
17446035553Spatrick_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
17546035553Spatrick_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
17646035553Spatrick_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
17746035553Spatrick#endif
17846035553Spatrick
17946035553Spatricktypedef void (*terminate_handler)();
18046035553Spatrick_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
18146035553Spatrick_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
18246035553Spatrick_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
18346035553Spatrick
18446035553Spatrick_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
18546035553Spatrick_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
18646035553Spatrick
18746035553Spatrickclass _LIBCPP_TYPE_VIS exception_ptr;
18846035553Spatrick
18946035553Spatrick_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
19046035553Spatrick_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
19146035553Spatrick
19246035553Spatrick#ifndef _LIBCPP_ABI_MICROSOFT
19346035553Spatrick
19446035553Spatrickclass _LIBCPP_TYPE_VIS exception_ptr
19546035553Spatrick{
19646035553Spatrick    void* __ptr_;
19746035553Spatrickpublic:
19846035553Spatrick    _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
19946035553Spatrick    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
20046035553Spatrick
20146035553Spatrick    exception_ptr(const exception_ptr&) _NOEXCEPT;
20246035553Spatrick    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
20346035553Spatrick    ~exception_ptr() _NOEXCEPT;
20446035553Spatrick
20576d0caaeSpatrick    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT
20646035553Spatrick    {return __ptr_ != nullptr;}
20746035553Spatrick
20846035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
20946035553Spatrick    bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
21046035553Spatrick        {return __x.__ptr_ == __y.__ptr_;}
21146035553Spatrick
21246035553Spatrick    friend _LIBCPP_INLINE_VISIBILITY
21346035553Spatrick    bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
21446035553Spatrick        {return !(__x == __y);}
21546035553Spatrick
21646035553Spatrick    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
21746035553Spatrick    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
21846035553Spatrick};
21946035553Spatrick
22046035553Spatricktemplate<class _Ep>
22146035553Spatrick_LIBCPP_INLINE_VISIBILITY exception_ptr
22246035553Spatrickmake_exception_ptr(_Ep __e) _NOEXCEPT
22346035553Spatrick{
22446035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
22546035553Spatrick    try
22646035553Spatrick    {
22746035553Spatrick        throw __e;
22846035553Spatrick    }
22946035553Spatrick    catch (...)
23046035553Spatrick    {
23146035553Spatrick        return current_exception();
23246035553Spatrick    }
23346035553Spatrick#else
23446035553Spatrick    ((void)__e);
23546035553Spatrick    _VSTD::abort();
23646035553Spatrick#endif
23746035553Spatrick}
23846035553Spatrick
23946035553Spatrick#else // _LIBCPP_ABI_MICROSOFT
24046035553Spatrick
24146035553Spatrickclass _LIBCPP_TYPE_VIS exception_ptr
24246035553Spatrick{
243*4bdff4beSrobert_LIBCPP_DIAGNOSTIC_PUSH
244*4bdff4beSrobert_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
24546035553Spatrick    void* __ptr1_;
24646035553Spatrick    void* __ptr2_;
247*4bdff4beSrobert_LIBCPP_DIAGNOSTIC_POP
24846035553Spatrickpublic:
24946035553Spatrick    exception_ptr() _NOEXCEPT;
25046035553Spatrick    exception_ptr(nullptr_t) _NOEXCEPT;
25146035553Spatrick    exception_ptr(const exception_ptr& __other) _NOEXCEPT;
25246035553Spatrick    exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
25346035553Spatrick    exception_ptr& operator=(nullptr_t) _NOEXCEPT;
25446035553Spatrick    ~exception_ptr() _NOEXCEPT;
25576d0caaeSpatrick    explicit operator bool() const _NOEXCEPT;
25646035553Spatrick};
25746035553Spatrick
25846035553Spatrick_LIBCPP_FUNC_VIS
25946035553Spatrickbool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
26046035553Spatrick
26146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
26246035553Spatrickbool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
26346035553Spatrick    {return !(__x == __y);}
26446035553Spatrick
26546035553Spatrick_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
26646035553Spatrick
26746035553Spatrick_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
26846035553Spatrick_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
269*4bdff4beSrobert_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
27046035553Spatrick
27146035553Spatrick// This is a built-in template function which automagically extracts the required
27246035553Spatrick// information.
27346035553Spatricktemplate <class _E> void *__GetExceptionInfo(_E);
27446035553Spatrick
27546035553Spatricktemplate<class _Ep>
27646035553Spatrick_LIBCPP_INLINE_VISIBILITY exception_ptr
27746035553Spatrickmake_exception_ptr(_Ep __e) _NOEXCEPT
27846035553Spatrick{
27946035553Spatrick  return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
28046035553Spatrick}
28146035553Spatrick
28246035553Spatrick#endif // _LIBCPP_ABI_MICROSOFT
28346035553Spatrick// nested_exception
28446035553Spatrick
28546035553Spatrickclass _LIBCPP_EXCEPTION_ABI nested_exception
28646035553Spatrick{
28746035553Spatrick    exception_ptr __ptr_;
28846035553Spatrickpublic:
28946035553Spatrick    nested_exception() _NOEXCEPT;
29046035553Spatrick//     nested_exception(const nested_exception&) noexcept = default;
29146035553Spatrick//     nested_exception& operator=(const nested_exception&) noexcept = default;
29246035553Spatrick    virtual ~nested_exception() _NOEXCEPT;
29346035553Spatrick
29446035553Spatrick    // access functions
29546035553Spatrick    _LIBCPP_NORETURN void rethrow_nested() const;
29646035553Spatrick    _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}
29746035553Spatrick};
29846035553Spatrick
29946035553Spatricktemplate <class _Tp>
30046035553Spatrickstruct __nested
30146035553Spatrick    : public _Tp,
30246035553Spatrick      public nested_exception
30346035553Spatrick{
30446035553Spatrick    _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}
30546035553Spatrick};
30646035553Spatrick
30746035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
30846035553Spatricktemplate <class _Tp, class _Up, bool>
30946035553Spatrickstruct __throw_with_nested;
31046035553Spatrick
31146035553Spatricktemplate <class _Tp, class _Up>
31246035553Spatrickstruct __throw_with_nested<_Tp, _Up, true> {
31346035553Spatrick    _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
31446035553Spatrick    __do_throw(_Tp&& __t)
31546035553Spatrick    {
31676d0caaeSpatrick        throw __nested<_Up>(static_cast<_Tp&&>(__t));
31746035553Spatrick    }
31846035553Spatrick};
31946035553Spatrick
32046035553Spatricktemplate <class _Tp, class _Up>
32146035553Spatrickstruct __throw_with_nested<_Tp, _Up, false> {
32246035553Spatrick    _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
32346035553Spatrick#ifndef _LIBCPP_CXX03_LANG
32446035553Spatrick    __do_throw(_Tp&& __t)
32546035553Spatrick#else
32646035553Spatrick    __do_throw (_Tp& __t)
32746035553Spatrick#endif // _LIBCPP_CXX03_LANG
32846035553Spatrick    {
32976d0caaeSpatrick        throw static_cast<_Tp&&>(__t);
33046035553Spatrick    }
33146035553Spatrick};
33246035553Spatrick#endif
33346035553Spatrick
33446035553Spatricktemplate <class _Tp>
335*4bdff4beSrobert_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
33646035553Spatrickvoid
33746035553Spatrickthrow_with_nested(_Tp&& __t)
33846035553Spatrick{
33946035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
34046035553Spatrick    typedef typename decay<_Tp>::type _Up;
34146035553Spatrick    static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
34246035553Spatrick    __throw_with_nested<_Tp, _Up,
34346035553Spatrick        is_class<_Up>::value &&
34446035553Spatrick        !is_base_of<nested_exception, _Up>::value &&
34546035553Spatrick        !__libcpp_is_final<_Up>::value>::
34676d0caaeSpatrick            __do_throw(static_cast<_Tp&&>(__t));
34746035553Spatrick#else
34846035553Spatrick    ((void)__t);
34946035553Spatrick    // FIXME: Make this abort
35046035553Spatrick#endif
35146035553Spatrick}
35246035553Spatrick
35346035553Spatricktemplate <class _From, class _To>
354*4bdff4beSrobertstruct __can_dynamic_cast : _BoolConstant<
35546035553Spatrick              is_polymorphic<_From>::value &&
35646035553Spatrick                 (!is_base_of<_To, _From>::value ||
357*4bdff4beSrobert                   is_convertible<const _From*, const _To*>::value)> {};
35846035553Spatrick
35946035553Spatricktemplate <class _Ep>
36046035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
36146035553Spatrickvoid
36246035553Spatrickrethrow_if_nested(const _Ep& __e,
363*4bdff4beSrobert                  __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
36446035553Spatrick{
36546035553Spatrick    const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
36646035553Spatrick    if (__nep)
36746035553Spatrick        __nep->rethrow_nested();
36846035553Spatrick}
36946035553Spatrick
37046035553Spatricktemplate <class _Ep>
37146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
37246035553Spatrickvoid
37346035553Spatrickrethrow_if_nested(const _Ep&,
374*4bdff4beSrobert                  __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
37546035553Spatrick{
37646035553Spatrick}
37746035553Spatrick
378*4bdff4beSrobert} // namespace std
379*4bdff4beSrobert
380*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
381*4bdff4beSrobert#  include <type_traits>
382*4bdff4beSrobert#endif
38346035553Spatrick
38446035553Spatrick#endif // _LIBCPP_EXCEPTION
385