1*38fd1498Szrj // Methods for Exception Support for -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2014-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj //
26*38fd1498Szrj // ISO C++ 14882: 19.1  Exception classes
27*38fd1498Szrj //
28*38fd1498Szrj 
29*38fd1498Szrj // Enable hooks for support for the Transactional Memory TS (N4514).
30*38fd1498Szrj #define _GLIBCXX_TM_TS_INTERNAL
31*38fd1498Szrj void
32*38fd1498Szrj _txnal_cow_string_C1_for_exceptions(void* that, const char* s, void* exc);
33*38fd1498Szrj const char*
34*38fd1498Szrj _txnal_cow_string_c_str(const void* that);
35*38fd1498Szrj void
36*38fd1498Szrj _txnal_cow_string_D1(void* that);
37*38fd1498Szrj void
38*38fd1498Szrj _txnal_cow_string_D1_commit(void* that);
39*38fd1498Szrj void*
40*38fd1498Szrj _txnal_logic_error_get_msg(void* e);
41*38fd1498Szrj void*
42*38fd1498Szrj _txnal_runtime_error_get_msg(void* e);
43*38fd1498Szrj 
44*38fd1498Szrj // All exception classes still use the classic COW std::string.
45*38fd1498Szrj #define _GLIBCXX_USE_CXX11_ABI 0
46*38fd1498Szrj #define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
47*38fd1498Szrj #define __cow_string __cow_stringxxx
48*38fd1498Szrj #include <stdexcept>
49*38fd1498Szrj #include <system_error>
50*38fd1498Szrj #undef __cow_string
51*38fd1498Szrj 
52*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
53*38fd1498Szrj {
54*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
55*38fd1498Szrj 
56*38fd1498Szrj   // Copy constructors and assignment operators defined using COW std::string
57*38fd1498Szrj 
logic_error(const logic_error & e)58*38fd1498Szrj   logic_error::logic_error(const logic_error& e) noexcept
59*38fd1498Szrj   : _M_msg(e._M_msg) { }
60*38fd1498Szrj 
operator =(const logic_error & e)61*38fd1498Szrj   logic_error& logic_error::operator=(const logic_error& e) noexcept
62*38fd1498Szrj   { _M_msg = e._M_msg; return *this; }
63*38fd1498Szrj 
runtime_error(const runtime_error & e)64*38fd1498Szrj   runtime_error::runtime_error(const runtime_error& e) noexcept
65*38fd1498Szrj   : _M_msg(e._M_msg) { }
66*38fd1498Szrj 
67*38fd1498Szrj   runtime_error&
operator =(const runtime_error & e)68*38fd1498Szrj   runtime_error::operator=(const runtime_error& e) noexcept
69*38fd1498Szrj   { _M_msg = e._M_msg; return *this; }
70*38fd1498Szrj 
71*38fd1498Szrj   // New C++11 constructors:
72*38fd1498Szrj 
logic_error(const char * __arg)73*38fd1498Szrj   logic_error::logic_error(const char* __arg)
74*38fd1498Szrj   : exception(), _M_msg(__arg) { }
75*38fd1498Szrj 
domain_error(const char * __arg)76*38fd1498Szrj   domain_error::domain_error(const char* __arg)
77*38fd1498Szrj   : logic_error(__arg) { }
78*38fd1498Szrj 
invalid_argument(const char * __arg)79*38fd1498Szrj   invalid_argument::invalid_argument(const char* __arg)
80*38fd1498Szrj   : logic_error(__arg) { }
81*38fd1498Szrj 
length_error(const char * __arg)82*38fd1498Szrj   length_error::length_error(const char* __arg)
83*38fd1498Szrj   : logic_error(__arg) { }
84*38fd1498Szrj 
out_of_range(const char * __arg)85*38fd1498Szrj   out_of_range::out_of_range(const char* __arg)
86*38fd1498Szrj   : logic_error(__arg) { }
87*38fd1498Szrj 
runtime_error(const char * __arg)88*38fd1498Szrj   runtime_error::runtime_error(const char* __arg)
89*38fd1498Szrj   : exception(), _M_msg(__arg) { }
90*38fd1498Szrj 
range_error(const char * __arg)91*38fd1498Szrj   range_error::range_error(const char* __arg)
92*38fd1498Szrj   : runtime_error(__arg) { }
93*38fd1498Szrj 
overflow_error(const char * __arg)94*38fd1498Szrj   overflow_error::overflow_error(const char* __arg)
95*38fd1498Szrj   : runtime_error(__arg) { }
96*38fd1498Szrj 
underflow_error(const char * __arg)97*38fd1498Szrj   underflow_error::underflow_error(const char* __arg)
98*38fd1498Szrj   : runtime_error(__arg) { }
99*38fd1498Szrj 
100*38fd1498Szrj #if _GLIBCXX_USE_DUAL_ABI
101*38fd1498Szrj   // Converting constructor from COW std::string to SSO string.
__sso_string(const string & s)102*38fd1498Szrj   __sso_string::__sso_string(const string& s)
103*38fd1498Szrj   : __sso_string(s.c_str(), s.length()) { }
104*38fd1498Szrj 
105*38fd1498Szrj   // Redefine __cow_string so that we can define and export its members
106*38fd1498Szrj   // in terms of the COW std::string.
107*38fd1498Szrj   struct __cow_string
108*38fd1498Szrj   {
109*38fd1498Szrj     union {
110*38fd1498Szrj       const char* _M_p;
111*38fd1498Szrj       char _M_bytes[sizeof(_M_p)];
112*38fd1498Szrj       std::string _M_str;
113*38fd1498Szrj     };
114*38fd1498Szrj 
115*38fd1498Szrj     __cow_string();
116*38fd1498Szrj     __cow_string(const std::string& s);
117*38fd1498Szrj     __cow_string(const char*, size_t n);
118*38fd1498Szrj     __cow_string(const __cow_string&) noexcept;
119*38fd1498Szrj     __cow_string& operator=(const __cow_string&) noexcept;
120*38fd1498Szrj     ~__cow_string();
121*38fd1498Szrj     __cow_string(__cow_string&&) noexcept;
122*38fd1498Szrj     __cow_string& operator=(__cow_string&&) noexcept;
123*38fd1498Szrj   };
124*38fd1498Szrj 
__cow_string()125*38fd1498Szrj   __cow_string::__cow_string() : _M_str() { }
126*38fd1498Szrj 
__cow_string(const std::string & s)127*38fd1498Szrj   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
128*38fd1498Szrj 
__cow_string(const char * s,size_t n)129*38fd1498Szrj   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
130*38fd1498Szrj 
__cow_string(const __cow_string & s)131*38fd1498Szrj   __cow_string::__cow_string(const __cow_string& s) noexcept
132*38fd1498Szrj   : _M_str(s._M_str) { }
133*38fd1498Szrj 
134*38fd1498Szrj   __cow_string&
operator =(const __cow_string & s)135*38fd1498Szrj   __cow_string::operator=(const __cow_string& s) noexcept
136*38fd1498Szrj   {
137*38fd1498Szrj     _M_str = s._M_str;
138*38fd1498Szrj     return *this;
139*38fd1498Szrj   }
140*38fd1498Szrj 
~__cow_string()141*38fd1498Szrj   __cow_string::~__cow_string() { _M_str.~basic_string(); }
142*38fd1498Szrj 
__cow_string(__cow_string && s)143*38fd1498Szrj   __cow_string::__cow_string(__cow_string&& s) noexcept
144*38fd1498Szrj   : _M_str(std::move(s._M_str)) { }
145*38fd1498Szrj 
146*38fd1498Szrj   __cow_string&
operator =(__cow_string && s)147*38fd1498Szrj   __cow_string::operator=(__cow_string&& s) noexcept
148*38fd1498Szrj   {
149*38fd1498Szrj     _M_str = std::move(s._M_str);
150*38fd1498Szrj     return *this;
151*38fd1498Szrj   }
152*38fd1498Szrj 
153*38fd1498Szrj   static_assert(sizeof(__cow_string) == sizeof(std::string),
154*38fd1498Szrj                 "sizeof(std::string) has changed");
155*38fd1498Szrj   static_assert(alignof(__cow_string) == alignof(std::string),
156*38fd1498Szrj                 "alignof(std::string) has changed");
157*38fd1498Szrj #endif
158*38fd1498Szrj 
159*38fd1498Szrj   // Return error_category::message() as an SSO string
160*38fd1498Szrj   __sso_string
_M_message(int i) const161*38fd1498Szrj   error_category::_M_message(int i) const
162*38fd1498Szrj   {
163*38fd1498Szrj     string msg = this->message(i);
164*38fd1498Szrj     return {msg.c_str(), msg.length()};
165*38fd1498Szrj   }
166*38fd1498Szrj 
167*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
168*38fd1498Szrj } // namespace
169*38fd1498Szrj 
170*38fd1498Szrj // Support for the Transactional Memory TS (N4514).
171*38fd1498Szrj //
172*38fd1498Szrj // logic_error and runtime_error both carry a message in the form of a COW
173*38fd1498Szrj // string.  This COW string is never made visible to users of the exception
174*38fd1498Szrj // because what() returns a C string.  The COW string can be constructed as
175*38fd1498Szrj // either a copy of a COW string of another logic_error/runtime_error, or
176*38fd1498Szrj // using a C string or SSO string; thus, the COW string's _Rep is only
177*38fd1498Szrj // accessed by logic_error operations.  We control all txnal clones of those
178*38fd1498Szrj // operations and thus can ensure that _Rep is never accessed transactionally.
179*38fd1498Szrj // Furthermore, _Rep will always have been allocated or deallocated via
180*38fd1498Szrj // global new or delete, so nontransactional writes we do to _Rep cannot
181*38fd1498Szrj // interfere with transactional accesses.
182*38fd1498Szrj 
183*38fd1498Szrj // We depend on having support for referencing functions declared weak that
184*38fd1498Szrj // are not defined by us.  Without such support, the exceptions will not be
185*38fd1498Szrj // declared transaction-safe, so we just don't provide transactional clones
186*38fd1498Szrj // in this case.
187*38fd1498Szrj #if _GLIBCXX_USE_WEAK_REF
188*38fd1498Szrj 
189*38fd1498Szrj extern "C" {
190*38fd1498Szrj 
191*38fd1498Szrj #ifndef _GLIBCXX_MANGLE_SIZE_T
192*38fd1498Szrj #error Mangled name of size_t type not defined.
193*38fd1498Szrj #endif
194*38fd1498Szrj #define CONCAT1(x,y)		x##y
195*38fd1498Szrj #define CONCAT(x,y)		CONCAT1(x,y)
196*38fd1498Szrj #define _ZGTtnaX		CONCAT(_ZGTtna,_GLIBCXX_MANGLE_SIZE_T)
197*38fd1498Szrj 
198*38fd1498Szrj #ifdef __i386__
199*38fd1498Szrj /* Only for 32-bit x86.  */
200*38fd1498Szrj # define ITM_REGPARM	__attribute__((regparm(2)))
201*38fd1498Szrj #else
202*38fd1498Szrj # define ITM_REGPARM
203*38fd1498Szrj #endif
204*38fd1498Szrj 
205*38fd1498Szrj // Declare all libitm symbols we rely on, but make them weak so that we do
206*38fd1498Szrj // not depend on libitm.
207*38fd1498Szrj extern void* _ZGTtnaX (size_t sz) __attribute__((weak));
208*38fd1498Szrj extern void _ZGTtdlPv (void* ptr) __attribute__((weak));
209*38fd1498Szrj extern uint8_t _ITM_RU1(const uint8_t *p)
210*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
211*38fd1498Szrj extern uint16_t _ITM_RU2(const uint16_t *p)
212*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
213*38fd1498Szrj extern uint32_t _ITM_RU4(const uint32_t *p)
214*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
215*38fd1498Szrj extern uint64_t _ITM_RU8(const uint64_t *p)
216*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
217*38fd1498Szrj extern void _ITM_memcpyRtWn(void *, const void *, size_t)
218*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
219*38fd1498Szrj extern void _ITM_memcpyRnWt(void *, const void *, size_t)
220*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
221*38fd1498Szrj extern void _ITM_addUserCommitAction(void (*)(void *), uint64_t, void *)
222*38fd1498Szrj   ITM_REGPARM __attribute__((weak));
223*38fd1498Szrj 
224*38fd1498Szrj }
225*38fd1498Szrj 
226*38fd1498Szrj // A transactional version of basic_string::basic_string(const char *s)
227*38fd1498Szrj // that also notifies the TM runtime about allocations belonging to this
228*38fd1498Szrj // exception.
229*38fd1498Szrj void
_txnal_cow_string_C1_for_exceptions(void * that,const char * s,void * exc)230*38fd1498Szrj _txnal_cow_string_C1_for_exceptions(void* that, const char* s,
231*38fd1498Szrj 				    void *exc __attribute__((unused)))
232*38fd1498Szrj {
233*38fd1498Szrj   typedef std::basic_string<char> bs_type;
234*38fd1498Szrj   bs_type *bs = (bs_type*) that;
235*38fd1498Szrj 
236*38fd1498Szrj   // First, do a transactional strlen, but including the trailing zero.
237*38fd1498Szrj   bs_type::size_type len = 1;
238*38fd1498Szrj   for (const char *ss = s; _ITM_RU1((const uint8_t*) ss) != 0; ss++, len++);
239*38fd1498Szrj 
240*38fd1498Szrj 
241*38fd1498Szrj   // Allocate memory for the string and the refcount.  We use the
242*38fd1498Szrj   // transactional clone of global new[]; if this throws, it will do so in a
243*38fd1498Szrj   // transaction-compatible way.
244*38fd1498Szrj   // The allocation belongs to this exception, so tell the runtime about it.
245*38fd1498Szrj   // TODO Once this is supported, link the following allocation to this
246*38fd1498Szrj   // exception: void *prev = _ITM_setAssociatedException(exc);
247*38fd1498Szrj   bs_type::_Rep *rep;
248*38fd1498Szrj   __try
249*38fd1498Szrj     {
250*38fd1498Szrj       rep = (bs_type::_Rep*) _ZGTtnaX (len + sizeof (bs_type::_Rep));
251*38fd1498Szrj     }
252*38fd1498Szrj   __catch (...)
253*38fd1498Szrj     {
254*38fd1498Szrj       // Pop the association with this exception.
255*38fd1498Szrj       // TODO Once this is supported, link the following allocation to this
256*38fd1498Szrj       // exception: _ITM_setAssociatedException(prev);
257*38fd1498Szrj       // We do not need to instrument a rethrow.
258*38fd1498Szrj       __throw_exception_again;
259*38fd1498Szrj     }
260*38fd1498Szrj   // Pop the association with this exception.
261*38fd1498Szrj   // TODO Once this is supported, link the following allocation to this
262*38fd1498Szrj   // exception: _ITM_setAssociatedException(prev);
263*38fd1498Szrj 
264*38fd1498Szrj   // Now initialize the rest of the string and copy the C string.  The memory
265*38fd1498Szrj   // will be freshly allocated, so nontransactional accesses are sufficient,
266*38fd1498Szrj   // including the writes when copying the string (see above).
267*38fd1498Szrj   rep->_M_set_sharable();
268*38fd1498Szrj   rep->_M_length = rep->_M_capacity = len - 1;
269*38fd1498Szrj   _ITM_memcpyRtWn(rep->_M_refdata(), s, len);
270*38fd1498Szrj   new (&bs->_M_dataplus) bs_type::_Alloc_hider(rep->_M_refdata(),
271*38fd1498Szrj 					       bs_type::allocator_type());
272*38fd1498Szrj }
273*38fd1498Szrj 
txnal_read_ptr(void * const * ptr)274*38fd1498Szrj static void* txnal_read_ptr(void* const * ptr)
275*38fd1498Szrj {
276*38fd1498Szrj   static_assert(sizeof(uint64_t) == sizeof(void*)
277*38fd1498Szrj 		|| sizeof(uint32_t) == sizeof(void*)
278*38fd1498Szrj 		|| sizeof(uint16_t) == sizeof(void*),
279*38fd1498Szrj 		"Pointers must be 16 bits, 32 bits or 64 bits wide");
280*38fd1498Szrj #if __UINTPTR_MAX__ == __UINT64_MAX__
281*38fd1498Szrj   return (void*)_ITM_RU8((const uint64_t*)ptr);
282*38fd1498Szrj #elif __UINTPTR_MAX__ == __UINT32_MAX__
283*38fd1498Szrj   return (void*)_ITM_RU4((const uint32_t*)ptr);
284*38fd1498Szrj #else
285*38fd1498Szrj   return (void*)_ITM_RU2((const uint16_t*)ptr);
286*38fd1498Szrj #endif
287*38fd1498Szrj }
288*38fd1498Szrj 
289*38fd1498Szrj // We must access the data pointer in the COW string transactionally because
290*38fd1498Szrj // another transaction can delete the string and reuse the memory.
291*38fd1498Szrj const char*
_txnal_cow_string_c_str(const void * that)292*38fd1498Szrj _txnal_cow_string_c_str(const void* that)
293*38fd1498Szrj {
294*38fd1498Szrj   typedef std::basic_string<char> bs_type;
295*38fd1498Szrj   const bs_type *bs = (const bs_type*) that;
296*38fd1498Szrj 
297*38fd1498Szrj   return (const char*) txnal_read_ptr((void**)&bs->_M_dataplus._M_p);
298*38fd1498Szrj }
299*38fd1498Szrj 
300*38fd1498Szrj #if _GLIBCXX_USE_DUAL_ABI
301*38fd1498Szrj const char*
_txnal_sso_string_c_str(const void * that)302*38fd1498Szrj _txnal_sso_string_c_str(const void* that)
303*38fd1498Szrj {
304*38fd1498Szrj   return (const char*) txnal_read_ptr(
305*38fd1498Szrj       (void* const*)const_cast<char* const*>(
306*38fd1498Szrj 	  &((const std::__sso_string*) that)->_M_s._M_p));
307*38fd1498Szrj }
308*38fd1498Szrj #endif
309*38fd1498Szrj 
310*38fd1498Szrj void
_txnal_cow_string_D1_commit(void * data)311*38fd1498Szrj _txnal_cow_string_D1_commit(void* data)
312*38fd1498Szrj {
313*38fd1498Szrj   typedef std::basic_string<char> bs_type;
314*38fd1498Szrj   bs_type::_Rep *rep = (bs_type::_Rep*) data;
315*38fd1498Szrj   rep->_M_dispose(bs_type::allocator_type());
316*38fd1498Szrj }
317*38fd1498Szrj 
318*38fd1498Szrj void
_txnal_cow_string_D1(void * that)319*38fd1498Szrj _txnal_cow_string_D1(void* that)
320*38fd1498Szrj {
321*38fd1498Szrj   typedef std::basic_string<char> bs_type;
322*38fd1498Szrj   bs_type::_Rep *rep = reinterpret_cast<bs_type::_Rep*>(
323*38fd1498Szrj       const_cast<char*>(_txnal_cow_string_c_str(that))) - 1;
324*38fd1498Szrj 
325*38fd1498Szrj   // The string can be shared, in which case we would need to decrement the
326*38fd1498Szrj   // reference count.  We cannot undo that because we might lose the string
327*38fd1498Szrj   // otherwise.  Therefore, we register a commit action that will dispose of
328*38fd1498Szrj   // the string's _Rep.
329*38fd1498Szrj   enum {_ITM_noTransactionId  = 1};
330*38fd1498Szrj   _ITM_addUserCommitAction(_txnal_cow_string_D1_commit, _ITM_noTransactionId,
331*38fd1498Szrj 			   rep);
332*38fd1498Szrj }
333*38fd1498Szrj 
334*38fd1498Szrj void*
_txnal_logic_error_get_msg(void * e)335*38fd1498Szrj _txnal_logic_error_get_msg(void* e)
336*38fd1498Szrj {
337*38fd1498Szrj   std::logic_error* le = (std::logic_error*) e;
338*38fd1498Szrj   return &le->_M_msg;
339*38fd1498Szrj }
340*38fd1498Szrj 
341*38fd1498Szrj void*
_txnal_runtime_error_get_msg(void * e)342*38fd1498Szrj _txnal_runtime_error_get_msg(void* e)
343*38fd1498Szrj {
344*38fd1498Szrj   std::runtime_error* le = (std::runtime_error*) e;
345*38fd1498Szrj   return &le->_M_msg;
346*38fd1498Szrj }
347*38fd1498Szrj 
348*38fd1498Szrj // The constructors are only declared transaction-safe if the C++11 ABI is
349*38fd1498Szrj // used for std::string and the exception classes use a COW string internally.
350*38fd1498Szrj // A user must not call these constructors otherwise; if they do, it will
351*38fd1498Szrj // result in undefined behavior, which is in this case not initializing this
352*38fd1498Szrj // string.
353*38fd1498Szrj #if _GLIBCXX_USE_DUAL_ABI
354*38fd1498Szrj #define CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)			\
355*38fd1498Szrj void									\
356*38fd1498Szrj _ZGTtNSt##NAME##C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
357*38fd1498Szrj     CLASS* that, const std::__sso_string& s)				\
358*38fd1498Szrj {									\
359*38fd1498Szrj   CLASS e("");								\
360*38fd1498Szrj   _ITM_memcpyRnWt(that, &e, sizeof(CLASS));				\
361*38fd1498Szrj   /* Get the C string from the SSO string.  */				\
362*38fd1498Szrj   _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that),	\
363*38fd1498Szrj 				      _txnal_sso_string_c_str(&s), that); \
364*38fd1498Szrj }									\
365*38fd1498Szrj void									\
366*38fd1498Szrj _ZGTtNSt##NAME##C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
367*38fd1498Szrj     CLASS*, const std::__sso_string&) __attribute__((alias		\
368*38fd1498Szrj ("_ZGTtNSt" #NAME							\
369*38fd1498Szrj   "C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")));
370*38fd1498Szrj #else
371*38fd1498Szrj #define CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)
372*38fd1498Szrj #endif
373*38fd1498Szrj 
374*38fd1498Szrj // This macro defines transaction constructors and destructors for a specific
375*38fd1498Szrj // exception class.  NAME is the variable part of the mangled name, CLASS is
376*38fd1498Szrj // the class name, and BASE must be logic_error or runtime_error (which is
377*38fd1498Szrj // then used to call the proper friend function that can return a pointer to
378*38fd1498Szrj // the _M_msg member declared by the given (base) class).
379*38fd1498Szrj #define CTORDTOR(NAME, CLASS, BASE)					\
380*38fd1498Szrj void									\
381*38fd1498Szrj _ZGTtNSt##NAME##C1EPKc (CLASS* that, const char* s)			\
382*38fd1498Szrj {									\
383*38fd1498Szrj   /* This will use the singleton _Rep for an empty string and just	\
384*38fd1498Szrj      point to it instead of allocating memory.  Thus, we can use it as	\
385*38fd1498Szrj      source, copy it into the object we are constructing, and then	\
386*38fd1498Szrj      construct the COW string in the latter manually.  Note that the	\
387*38fd1498Szrj      exception classes will not be declared transaction_safe if the	\
388*38fd1498Szrj      shared empty _Rep is disabled with --enable-fully-dynamic-string	\
389*38fd1498Szrj      (in which case _GLIBCXX_FULLY_DYNAMIC_STRING is nonzero).  */	\
390*38fd1498Szrj   CLASS e("");								\
391*38fd1498Szrj   _ITM_memcpyRnWt(that, &e, sizeof(CLASS));				\
392*38fd1498Szrj   _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that),	\
393*38fd1498Szrj 				      s, that);				\
394*38fd1498Szrj }									\
395*38fd1498Szrj void									\
396*38fd1498Szrj _ZGTtNSt##NAME##C2EPKc (CLASS*, const char*)				\
397*38fd1498Szrj   __attribute__((alias ("_ZGTtNSt" #NAME "C1EPKc")));			\
398*38fd1498Szrj CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)					\
399*38fd1498Szrj void									\
400*38fd1498Szrj _ZGTtNSt##NAME##D1Ev(CLASS* that)					\
401*38fd1498Szrj { _txnal_cow_string_D1(_txnal_##BASE##_get_msg(that)); }		\
402*38fd1498Szrj void									\
403*38fd1498Szrj _ZGTtNSt##NAME##D2Ev(CLASS*)						\
404*38fd1498Szrj __attribute__((alias ("_ZGTtNSt" #NAME "D1Ev")));			\
405*38fd1498Szrj void									\
406*38fd1498Szrj _ZGTtNSt##NAME##D0Ev(CLASS* that)					\
407*38fd1498Szrj {									\
408*38fd1498Szrj   _ZGTtNSt##NAME##D1Ev(that);						\
409*38fd1498Szrj   _ZGTtdlPv(that);							\
410*38fd1498Szrj }
411*38fd1498Szrj 
412*38fd1498Szrj // Now create all transactional constructors and destructors, as well as the
413*38fd1498Szrj // two virtual what() functions.
414*38fd1498Szrj extern "C" {
415*38fd1498Szrj 
416*38fd1498Szrj CTORDTOR(11logic_error, std::logic_error, logic_error)
417*38fd1498Szrj 
418*38fd1498Szrj const char*
_ZGTtNKSt11logic_error4whatEv(const std::logic_error * that)419*38fd1498Szrj _ZGTtNKSt11logic_error4whatEv(const std::logic_error* that)
420*38fd1498Szrj {
421*38fd1498Szrj   return _txnal_cow_string_c_str(_txnal_logic_error_get_msg(
422*38fd1498Szrj       const_cast<std::logic_error*>(that)));
423*38fd1498Szrj }
424*38fd1498Szrj 
425*38fd1498Szrj CTORDTOR(12domain_error, std::domain_error, logic_error)
426*38fd1498Szrj CTORDTOR(16invalid_argument, std::invalid_argument, logic_error)
427*38fd1498Szrj CTORDTOR(12length_error, std::length_error, logic_error)
428*38fd1498Szrj CTORDTOR(12out_of_range, std::out_of_range, logic_error)
429*38fd1498Szrj 
430*38fd1498Szrj 
431*38fd1498Szrj CTORDTOR(13runtime_error, std::runtime_error, runtime_error)
432*38fd1498Szrj 
433*38fd1498Szrj const char*
_ZGTtNKSt13runtime_error4whatEv(const std::runtime_error * that)434*38fd1498Szrj _ZGTtNKSt13runtime_error4whatEv(const std::runtime_error* that)
435*38fd1498Szrj {
436*38fd1498Szrj   return _txnal_cow_string_c_str(_txnal_runtime_error_get_msg(
437*38fd1498Szrj       const_cast<std::runtime_error*>(that)));
438*38fd1498Szrj }
439*38fd1498Szrj 
440*38fd1498Szrj CTORDTOR(11range_error, std::range_error, runtime_error)
441*38fd1498Szrj CTORDTOR(14overflow_error, std::overflow_error, runtime_error)
442*38fd1498Szrj CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
443*38fd1498Szrj 
444*38fd1498Szrj }
445*38fd1498Szrj 
446*38fd1498Szrj #endif  // _GLIBCXX_USE_WEAK_REF
447