1// -*- C++ -*- std::terminate, std::unexpected and friends. 2// Copyright (C) 1994-2020 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 __terminate (get_terminate ()); 59} 60 61void 62__cxxabiv1::__unexpected (std::unexpected_handler handler) 63{ 64 handler(); 65 std::terminate (); 66} 67 68void 69std::unexpected () 70{ 71 __unexpected (get_unexpected ()); 72} 73 74std::terminate_handler 75std::set_terminate (std::terminate_handler func) throw() 76{ 77 if (!func) 78 func = _GLIBCXX_DEFAULT_TERM_HANDLER; 79 80 std::terminate_handler old; 81#if ATOMIC_POINTER_LOCK_FREE > 1 82 __atomic_exchange (&__terminate_handler, &func, &old, __ATOMIC_ACQ_REL); 83#else 84 __gnu_cxx::__scoped_lock l(mx); 85 old = __terminate_handler; 86 __terminate_handler = func; 87#endif 88 return old; 89} 90 91std::terminate_handler 92std::get_terminate () noexcept 93{ 94 std::terminate_handler func; 95#if ATOMIC_POINTER_LOCK_FREE > 1 96 __atomic_load (&__terminate_handler, &func, __ATOMIC_ACQUIRE); 97#else 98 __gnu_cxx::__scoped_lock l(mx); 99 func = __terminate_handler; 100#endif 101 return func; 102} 103 104std::unexpected_handler 105std::set_unexpected (std::unexpected_handler func) throw() 106{ 107 if (!func) 108 func = std::terminate; 109 110 std::unexpected_handler old; 111#if ATOMIC_POINTER_LOCK_FREE > 1 112 __atomic_exchange (&__unexpected_handler, &func, &old, __ATOMIC_ACQ_REL); 113#else 114 __gnu_cxx::__scoped_lock l(mx); 115 old = __unexpected_handler; 116 __unexpected_handler = func; 117#endif 118 return old; 119} 120 121std::unexpected_handler 122std::get_unexpected () noexcept 123{ 124 std::unexpected_handler func; 125#if ATOMIC_POINTER_LOCK_FREE > 1 126 __atomic_load (&__unexpected_handler, &func, __ATOMIC_ACQUIRE); 127#else 128 __gnu_cxx::__scoped_lock l(mx); 129 func = __unexpected_handler; 130#endif 131 return func; 132} 133