1// -*- C++ -*- std::terminate, std::unexpected and friends. 2// Copyright (C) 1994-2022 Free Software Foundation, Inc. 3// 4// This file is part of GCC. 5// 6// GCC is free software; you can redistribute it and/or modify 7// it under the terms of the GNU General Public License as published by 8// the Free Software Foundation; either version 3, or (at your option) 9// any later version. 10// 11// GCC is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15// 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25#include "typeinfo" 26#include "exception" 27#include <cstdlib> 28#include "unwind-cxx.h" 29#include "eh_term_handler.h" 30#include <bits/exception_defines.h> 31#include <bits/atomic_lockfree_defines.h> 32 33#if ATOMIC_POINTER_LOCK_FREE < 2 34#include <ext/concurrence.h> 35namespace 36{ 37 __gnu_cxx::__mutex mx; 38} 39#endif 40 41using namespace __cxxabiv1; 42 43void 44__cxxabiv1::__terminate (std::terminate_handler handler) throw () 45{ 46 __try 47 { 48 handler (); 49 std::abort (); 50 } 51 __catch(...) 52 { std::abort (); } 53} 54 55void 56std::terminate () throw() 57{ 58 __cxxabiv1::__terminate (get_terminate ()); 59} 60 61#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 62void 63__cxxabiv1::__unexpected (std::unexpected_handler handler) 64{ 65 handler(); 66 std::terminate (); 67} 68 69void 70std::unexpected () 71{ 72 __unexpected (get_unexpected ()); 73} 74 75std::terminate_handler 76std::set_terminate (std::terminate_handler func) throw() 77{ 78 if (!func) 79 func = _GLIBCXX_DEFAULT_TERM_HANDLER; 80 81 std::terminate_handler old; 82#if ATOMIC_POINTER_LOCK_FREE > 1 83 __atomic_exchange (&__terminate_handler, &func, &old, __ATOMIC_ACQ_REL); 84#else 85 __gnu_cxx::__scoped_lock l(mx); 86 old = __terminate_handler; 87 __terminate_handler = func; 88#endif 89 return old; 90} 91 92std::terminate_handler 93std::get_terminate () noexcept 94{ 95 std::terminate_handler func; 96#if ATOMIC_POINTER_LOCK_FREE > 1 97 __atomic_load (&__terminate_handler, &func, __ATOMIC_ACQUIRE); 98#else 99 __gnu_cxx::__scoped_lock l(mx); 100 func = __terminate_handler; 101#endif 102 return func; 103} 104 105std::unexpected_handler 106std::set_unexpected (std::unexpected_handler func) throw() 107{ 108 if (!func) 109 func = std::terminate; 110 111 std::unexpected_handler old; 112#if ATOMIC_POINTER_LOCK_FREE > 1 113 __atomic_exchange (&__unexpected_handler, &func, &old, __ATOMIC_ACQ_REL); 114#else 115 __gnu_cxx::__scoped_lock l(mx); 116 old = __unexpected_handler; 117 __unexpected_handler = func; 118#endif 119 return old; 120} 121 122std::unexpected_handler 123std::get_unexpected () noexcept 124{ 125 std::unexpected_handler func; 126#if ATOMIC_POINTER_LOCK_FREE > 1 127 __atomic_load (&__unexpected_handler, &func, __ATOMIC_ACQUIRE); 128#else 129 __gnu_cxx::__scoped_lock l(mx); 130 func = __unexpected_handler; 131#endif 132 return func; 133} 134