Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/c++abi/src/cxa_handlers.cpp
12346 views
1
//===------------------------- cxa_handlers.cpp ---------------------------===//
2
//
3
// The LLVM Compiler Infrastructure
4
//
5
// This file is dual licensed under the MIT and the University of Illinois Open
6
// Source Licenses. See LICENSE.TXT for details.
7
//
8
//
9
// This file implements the functionality associated with the terminate_handler,
10
// unexpected_handler, and new_handler.
11
//===----------------------------------------------------------------------===//
12
13
#include <stdexcept>
14
#include <new>
15
#include <exception>
16
#include "abort_message.h"
17
#include "cxxabi.h"
18
#include "cxa_handlers.hpp"
19
#include "cxa_exception.hpp"
20
#include "private_typeinfo.h"
21
#include "include/atomic_support.h"
22
23
namespace std
24
{
25
26
unexpected_handler
27
get_unexpected() _NOEXCEPT
28
{
29
return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire);
30
}
31
32
void
33
__unexpected(unexpected_handler func)
34
{
35
func();
36
// unexpected handler should not return
37
abort_message("unexpected_handler unexpectedly returned");
38
}
39
40
__attribute__((noreturn))
41
void
42
unexpected()
43
{
44
__unexpected(get_unexpected());
45
}
46
47
terminate_handler
48
get_terminate() _NOEXCEPT
49
{
50
return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire);
51
}
52
53
void
54
__terminate(terminate_handler func) _NOEXCEPT
55
{
56
#ifndef _LIBCXXABI_NO_EXCEPTIONS
57
try
58
{
59
#endif // _LIBCXXABI_NO_EXCEPTIONS
60
func();
61
// handler should not return
62
abort_message("terminate_handler unexpectedly returned");
63
#ifndef _LIBCXXABI_NO_EXCEPTIONS
64
}
65
catch (...)
66
{
67
// handler should not throw exception
68
abort_message("terminate_handler unexpectedly threw an exception");
69
}
70
#endif // _LIBCXXABI_NO_EXCEPTIONS
71
}
72
73
__attribute__((noreturn))
74
void
75
terminate() _NOEXCEPT
76
{
77
// If there might be an uncaught exception
78
using namespace __cxxabiv1;
79
__cxa_eh_globals* globals = __cxa_get_globals_fast();
80
if (globals)
81
{
82
__cxa_exception* exception_header = globals->caughtExceptions;
83
if (exception_header)
84
{
85
_Unwind_Exception* unwind_exception =
86
reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1;
87
if (__isOurExceptionClass(unwind_exception))
88
__terminate(exception_header->terminateHandler);
89
}
90
}
91
__terminate(get_terminate());
92
}
93
94
extern "C" {
95
new_handler __cxa_new_handler = 0;
96
}
97
98
new_handler
99
set_new_handler(new_handler handler) _NOEXCEPT
100
{
101
return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel);
102
}
103
104
new_handler
105
get_new_handler() _NOEXCEPT
106
{
107
return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire);
108
}
109
110
} // std
111
112