aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2006-04-12 16:12:00 +0000
committerPaolo Carlini <pcarlini@suse.de>2006-04-12 16:12:00 +0000
commitd91d418efff36798b5e67090452c7bf18f94c2ec (patch)
tree4d6376429e41d8ba1efdf2f25cfa8f241763818a
parente1598fe99d825879716ad9a28cec99dbff50fc68 (diff)
2006-04-12 Paolo Carlini <pcarlini@suse.de>
* include/std/std_stdexcept.h (class __exception_string): Add. (class logic_error, class runtime_error): Use it. * src/stdexcept.cc (_exception_string::_Rep::_M_destroy, __exception_string::__exception_string(const string&), __exception_string::operator=(const __exception_string&)): Define. * config/abi/pre/gnu.ver: Update exports. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/libstdcxx_so_7-branch@112888 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog.libstdcxx_so_7-branch9
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver2
-rw-r--r--libstdc++-v3/include/std/std_stdexcept.h64
-rw-r--r--libstdc++-v3/src/stdexcept.cc40
4 files changed, 111 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch
index 3a4626ce3f0..b8d2f6be5ea 100644
--- a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch
+++ b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch
@@ -1,3 +1,12 @@
+2006-04-12 Paolo Carlini <pcarlini@suse.de>
+
+ * include/std/std_stdexcept.h (class __exception_string): Add.
+ (class logic_error, class runtime_error): Use it.
+ * src/stdexcept.cc (_exception_string::_Rep::_M_destroy,
+ __exception_string::__exception_string(const string&),
+ __exception_string::operator=(const __exception_string&)): Define.
+ * config/abi/pre/gnu.ver: Update exports.
+
2006-04-11 Paolo Carlini <pcarlini@suse.de>
Merged to mainline at revision 112818.
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index f6be5e96867..0dfa152c01e 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -614,6 +614,8 @@ GLIBCXX_4.2 {
_ZNK9__gnu_cxx12__sso_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*;
_ZZN9__gnu_cxx12__sso_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE*;
+ _ZNSt18__exception_string*;
+
# DO NOT DELETE THIS LINE. Port-specific symbols, if any, will be here.
local:
diff --git a/libstdc++-v3/include/std/std_stdexcept.h b/libstdc++-v3/include/std/std_stdexcept.h
index 0104e54464e..a9e49cb16d5 100644
--- a/libstdc++-v3/include/std/std_stdexcept.h
+++ b/libstdc++-v3/include/std/std_stdexcept.h
@@ -1,6 +1,7 @@
// Standard exception classes -*- C++ -*-
-// Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -42,9 +43,66 @@
#include <exception>
#include <string>
+#include <bits/atomicity.h>
_GLIBCXX_BEGIN_NAMESPACE(std)
+ /** Reference-counted "mini-string" for internal use in the std exception
+ * classes, needed due to the no-throw requirements for copy-constructor
+ * and assignment operator, not fulfilled by sso_string. */
+ class __exception_string
+ {
+ struct _Rep
+ {
+ size_t _M_size;
+ _Atomic_word _M_refcount;
+
+ void
+ _M_destroy() throw();
+
+ void
+ _M_dispose() throw()
+ {
+ if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) <= 0)
+ _M_destroy();
+ }
+
+ char*
+ _M_refdata() throw()
+ { return reinterpret_cast<char*>(this + 1); }
+
+ char*
+ _M_refcopy() throw()
+ {
+ __gnu_cxx::__atomic_add(&_M_refcount, 1);
+ return _M_refdata();
+ }
+ };
+
+ char* _M_data;
+
+ _Rep*
+ _M_rep() const throw()
+ { return &((reinterpret_cast<_Rep*>(_M_data))[-1]); }
+
+ public:
+ __exception_string(const __exception_string& __ex_str)
+ : _M_data(__ex_str._M_rep()->_M_refcopy()) { }
+
+ __exception_string(const string& __str);
+
+ ~__exception_string()
+ { _M_rep()->_M_dispose(); }
+
+ __exception_string&
+ operator=(const __exception_string& __ex_str);
+
+ const char*
+ c_str() const
+ { return _M_data; }
+ };
+
+
/** Logic errors represent problems in the internal logic of a program;
* in theory, these are preventable, and even detectable before the
* program runs (e.g., violations of class invariants).
@@ -52,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
class logic_error : public exception
{
- string _M_msg;
+ __exception_string _M_msg;
public:
/** Takes a character string describing the error. */
@@ -106,7 +164,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
class runtime_error : public exception
{
- string _M_msg;
+ __exception_string _M_msg;
public:
/** Takes a character string describing the error. */
diff --git a/libstdc++-v3/src/stdexcept.cc b/libstdc++-v3/src/stdexcept.cc
index 19ac5779eb5..51449ede7e1 100644
--- a/libstdc++-v3/src/stdexcept.cc
+++ b/libstdc++-v3/src/stdexcept.cc
@@ -1,6 +1,7 @@
// Methods for Exception Support for -*- C++ -*-
-// Copyright (C) 1997, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+// 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -36,6 +37,43 @@
_GLIBCXX_BEGIN_NAMESPACE(std)
+ void
+ __exception_string::_Rep::
+ _M_destroy() throw()
+ {
+ allocator<char>().deallocate(reinterpret_cast<char*>(this),
+ sizeof(_Rep) + _M_size);
+ }
+
+ __exception_string::
+ __exception_string(const string& __str)
+ {
+ const size_t __size = __str.size() + 1;
+
+ void* __place = allocator<char>().allocate(sizeof(_Rep) + __size);
+ _Rep* __r = new (__place) _Rep;
+
+ memcpy(__r->_M_refdata(), __str.c_str(), __size);
+ __r->_M_size = __size;
+ __r->_M_refcount = 0;
+
+ _M_data = __r->_M_refdata();
+ }
+
+ __exception_string&
+ __exception_string::
+ operator=(const __exception_string& __ex_str)
+ {
+ if (_M_rep() != __ex_str._M_rep())
+ {
+ char* __tmp = __ex_str._M_rep()->_M_refcopy();
+ _M_rep()->_M_dispose();
+ _M_data = __tmp;
+ }
+ return *this;
+ }
+
+
logic_error::logic_error(const string& __arg)
: exception(), _M_msg(__arg) { }