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