]>
Commit | Line | Data |
---|---|---|
52a11cbf | 1 | // -*- C++ -*- Exception handling routines for catching. |
a945c346 | 2 | // Copyright (C) 2001-2024 Free Software Foundation, Inc. |
52a11cbf | 3 | // |
cbecceb9 | 4 | // This file is part of GCC. |
52a11cbf | 5 | // |
cbecceb9 | 6 | // GCC is free software; you can redistribute it and/or modify |
52a11cbf | 7 | // it under the terms of the GNU General Public License as published by |
748086b7 | 8 | // the Free Software Foundation; either version 3, or (at your option) |
52a11cbf RH |
9 | // any later version. |
10 | // | |
cbecceb9 | 11 | // GCC is distributed in the hope that it will be useful, |
52a11cbf RH |
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 | // | |
748086b7 JJ |
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. | |
52a11cbf | 19 | |
748086b7 JJ |
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/>. | |
52a11cbf | 24 | |
52a11cbf RH |
25 | #include <cstdlib> |
26 | #include "unwind-cxx.h" | |
27 | ||
28 | using namespace __cxxabiv1; | |
29 | ||
39609077 | 30 | extern "C" void * |
50da34bb | 31 | __cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) _GLIBCXX_NOTHROW |
39609077 RH |
32 | { |
33 | _Unwind_Exception *exceptionObject | |
34 | = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); | |
39609077 | 35 | |
617a1b71 | 36 | return __gxx_caught_object(exceptionObject); |
39609077 | 37 | } |
52a11cbf RH |
38 | |
39 | extern "C" void * | |
50da34bb | 40 | __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) _GLIBCXX_NOTHROW |
52a11cbf | 41 | { |
74a3070f JM |
42 | _Unwind_Exception *exceptionObject |
43 | = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); | |
52a11cbf RH |
44 | __cxa_eh_globals *globals = __cxa_get_globals (); |
45 | __cxa_exception *prev = globals->caughtExceptions; | |
a944ceb9 | 46 | __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); |
617a1b71 | 47 | void* objectp; |
a944ceb9 RH |
48 | |
49 | // Foreign exceptions can't be stacked here. If the exception stack is | |
50 | // empty, then fine. Otherwise we really have no choice but to terminate. | |
51 | // Note that this use of "header" is a lie. It's fine so long as we only | |
52 | // examine header->unwindHeader though. | |
617a1b71 | 53 | if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) |
a944ceb9 RH |
54 | { |
55 | if (prev != 0) | |
56 | std::terminate (); | |
57 | ||
58 | // Remember for end_catch and rethrow. | |
59 | globals->caughtExceptions = header; | |
60 | ||
61 | // ??? No sensible value to return; we don't know what the | |
62 | // object is, much less where it is in relation to the header. | |
63 | return 0; | |
64 | } | |
52a11cbf | 65 | |
a944ceb9 | 66 | int count = header->handlerCount; |
38f92567 RH |
67 | // Count is less than zero if this exception was rethrown from an |
68 | // immediately enclosing region. | |
52a11cbf | 69 | if (count < 0) |
52a11cbf RH |
70 | count = -count + 1; |
71 | else | |
38f92567 | 72 | count += 1; |
52a11cbf | 73 | header->handlerCount = count; |
38f92567 | 74 | globals->uncaughtExceptions -= 1; |
52a11cbf | 75 | |
52a11cbf RH |
76 | if (header != prev) |
77 | { | |
78 | header->nextException = prev; | |
79 | globals->caughtExceptions = header; | |
80 | } | |
81 | ||
617a1b71 | 82 | objectp = __gxx_caught_object(exceptionObject); |
83c214a8 TT |
83 | |
84 | PROBE2 (catch, objectp, header->exceptionType); | |
85 | ||
617a1b71 PB |
86 | #ifdef __ARM_EABI_UNWINDER__ |
87 | _Unwind_Complete(exceptionObject); | |
88 | #endif | |
89 | return objectp; | |
52a11cbf RH |
90 | } |
91 | ||
92 | ||
93 | extern "C" void | |
723acbd5 | 94 | __cxxabiv1::__cxa_end_catch () |
52a11cbf RH |
95 | { |
96 | __cxa_eh_globals *globals = __cxa_get_globals_fast (); | |
97 | __cxa_exception *header = globals->caughtExceptions; | |
52a11cbf | 98 | |
a944ceb9 RH |
99 | // A rethrow of a foreign exception will be removed from the |
100 | // the exception stack immediately by __cxa_rethrow. | |
101 | if (!header) | |
102 | return; | |
103 | ||
104 | // A foreign exception couldn't have been stacked (see above), | |
105 | // so by definition processing must be complete. | |
617a1b71 | 106 | if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) |
a944ceb9 RH |
107 | { |
108 | globals->caughtExceptions = 0; | |
109 | _Unwind_DeleteException (&header->unwindHeader); | |
110 | return; | |
111 | } | |
112 | ||
113 | int count = header->handlerCount; | |
52a11cbf RH |
114 | if (count < 0) |
115 | { | |
116 | // This exception was rethrown. Decrement the (inverted) catch | |
117 | // count and remove it from the chain when it reaches zero. | |
118 | if (++count == 0) | |
39609077 | 119 | globals->caughtExceptions = header->nextException; |
52a11cbf RH |
120 | } |
121 | else if (--count == 0) | |
122 | { | |
123 | // Handling for this exception is complete. Destroy the object. | |
124 | globals->caughtExceptions = header->nextException; | |
125 | _Unwind_DeleteException (&header->unwindHeader); | |
126 | return; | |
127 | } | |
128 | else if (count < 0) | |
129 | // A bug in the exception handling library or compiler. | |
a944ceb9 | 130 | std::terminate (); |
52a11cbf RH |
131 | |
132 | header->handlerCount = count; | |
133 | } | |
134 | ||
135 | ||
136 | bool | |
137 | std::uncaught_exception() throw() | |
138 | { | |
03e73da6 | 139 | #if __cpp_exceptions |
52a11cbf RH |
140 | __cxa_eh_globals *globals = __cxa_get_globals (); |
141 | return globals->uncaughtExceptions != 0; | |
03e73da6 FL |
142 | #else |
143 | return false; | |
144 | #endif | |
52a11cbf | 145 | } |
03a16cc4 VV |
146 | |
147 | int | |
148 | std::uncaught_exceptions() throw() | |
149 | { | |
03e73da6 | 150 | #if __cpp_exceptions |
03a16cc4 VV |
151 | __cxa_eh_globals *globals = __cxa_get_globals (); |
152 | return globals->uncaughtExceptions; | |
03e73da6 FL |
153 | #else |
154 | return 0; | |
155 | #endif | |
03a16cc4 | 156 | } |