xref: /freebsd/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#include <cstdio>
110b57cec5SDimitry Andric
120b57cec5SDimitry Andricnamespace std {
130b57cec5SDimitry Andric
1481ad6265SDimitry Andricstatic constinit std::terminate_handler __terminate_handler   = nullptr;
1581ad6265SDimitry Andricstatic constinit std::unexpected_handler __unexpected_handler = nullptr;
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric// libcxxrt provides implementations of these functions itself.
18*cb14a3feSDimitry Andricunexpected_handler set_unexpected(unexpected_handler func) noexcept {
190b57cec5SDimitry Andric  return __libcpp_atomic_exchange(&__unexpected_handler, func);
200b57cec5SDimitry Andric}
210b57cec5SDimitry Andric
22*cb14a3feSDimitry Andricunexpected_handler get_unexpected() noexcept { return __libcpp_atomic_load(&__unexpected_handler); }
230b57cec5SDimitry Andric
24*cb14a3feSDimitry Andric_LIBCPP_NORETURN void unexpected() {
250b57cec5SDimitry Andric  (*get_unexpected())();
260b57cec5SDimitry Andric  // unexpected handler should not return
270b57cec5SDimitry Andric  terminate();
280b57cec5SDimitry Andric}
290b57cec5SDimitry Andric
30*cb14a3feSDimitry Andricterminate_handler set_terminate(terminate_handler func) noexcept {
310b57cec5SDimitry Andric  return __libcpp_atomic_exchange(&__terminate_handler, func);
320b57cec5SDimitry Andric}
330b57cec5SDimitry Andric
34*cb14a3feSDimitry Andricterminate_handler get_terminate() noexcept { return __libcpp_atomic_load(&__terminate_handler); }
350b57cec5SDimitry Andric
36*cb14a3feSDimitry Andric_LIBCPP_NORETURN void terminate() noexcept {
3706c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
38*cb14a3feSDimitry Andric  try {
3906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
400b57cec5SDimitry Andric    (*get_terminate())();
410b57cec5SDimitry Andric    // handler should not return
420b57cec5SDimitry Andric    fprintf(stderr, "terminate_handler unexpectedly returned\n");
430b57cec5SDimitry Andric    ::abort();
4406c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
45*cb14a3feSDimitry Andric  } catch (...) {
460b57cec5SDimitry Andric    // handler should not throw exception
470b57cec5SDimitry Andric    fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
480b57cec5SDimitry Andric    ::abort();
490b57cec5SDimitry Andric  }
5006c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
510b57cec5SDimitry Andric}
520b57cec5SDimitry Andric
53fe6060f1SDimitry Andricbool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
540b57cec5SDimitry Andric
55*cb14a3feSDimitry Andricint uncaught_exceptions() noexcept {
560b57cec5SDimitry Andric#warning uncaught_exception not yet implemented
570b57cec5SDimitry Andric  fprintf(stderr, "uncaught_exceptions not yet implemented\n");
580b57cec5SDimitry Andric  ::abort();
590b57cec5SDimitry Andric}
600b57cec5SDimitry Andric
61*cb14a3feSDimitry Andricexception::~exception() noexcept {}
620b57cec5SDimitry Andric
63*cb14a3feSDimitry Andricconst char* exception::what() const noexcept { return "std::exception"; }
640b57cec5SDimitry Andric
65*cb14a3feSDimitry Andricbad_exception::~bad_exception() noexcept {}
660b57cec5SDimitry Andric
67*cb14a3feSDimitry Andricconst char* bad_exception::what() const noexcept { return "std::bad_exception"; }
680b57cec5SDimitry Andric
69*cb14a3feSDimitry Andricbad_alloc::bad_alloc() noexcept {}
700b57cec5SDimitry Andric
71*cb14a3feSDimitry Andricbad_alloc::~bad_alloc() noexcept {}
720b57cec5SDimitry Andric
73*cb14a3feSDimitry Andricconst char* bad_alloc::what() const noexcept { return "std::bad_alloc"; }
740b57cec5SDimitry Andric
75*cb14a3feSDimitry Andricbad_array_new_length::bad_array_new_length() noexcept {}
760b57cec5SDimitry Andric
77*cb14a3feSDimitry Andricbad_array_new_length::~bad_array_new_length() noexcept {}
780b57cec5SDimitry Andric
79*cb14a3feSDimitry Andricconst char* bad_array_new_length::what() const noexcept { return "bad_array_new_length"; }
800b57cec5SDimitry Andric
81*cb14a3feSDimitry Andricbad_cast::bad_cast() noexcept {}
820b57cec5SDimitry Andric
83*cb14a3feSDimitry Andricbad_typeid::bad_typeid() noexcept {}
840b57cec5SDimitry Andric
85*cb14a3feSDimitry Andricbad_cast::~bad_cast() noexcept {}
860b57cec5SDimitry Andric
87*cb14a3feSDimitry Andricconst char* bad_cast::what() const noexcept { return "std::bad_cast"; }
880b57cec5SDimitry Andric
89*cb14a3feSDimitry Andricbad_typeid::~bad_typeid() noexcept {}
900b57cec5SDimitry Andric
91*cb14a3feSDimitry Andricconst char* bad_typeid::what() const noexcept { return "std::bad_typeid"; }
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric} // namespace std
94