re PR other/28145 (C++ (throw() and catch(...) {/* fall through */ } ) and pthread...
authorJason Merrill <jason@redhat.com>
Mon, 7 May 2007 21:27:54 +0000 (17:27 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 7 May 2007 21:27:54 +0000 (17:27 -0400)
        PR c++/28145
        * libsupc++/cxxabi.h (__forced_unwind, __foreign_exception):
        New classes.
        * libsupc++/eh_exception.cc: Define their destructors.
        * config/abi/pre/gnu.ver: Export their type_infos.
        * config/abi/pre/gnu-versioned-namespace.ver: Likewise.
        * libsupc++/eh_personality.cc: A handler for abi::__forced_unwind
        matches a forced unwind, and a handler for abi::__foreign_exception
        matches a foreign exception.

        * include/bits/istream.tcc: Rethrow forced unwind.
        * include/bits/ostream.tcc: Likewise.
        * include/bits/ostream_insert.h: Likewise.
        * include/bits/basic_string.tcc (operator>>, getline): Likewise.
        * include/bits/fstream.tcc (basic_filebuf::close): Likewise.
        * include/ext/vstring.cc (operator>>, getline): Likewise.
        * src/istream.cc: Likewise.
        * src/compatibility.cc (basic_istream::ignore): Likewise.
        * include/std/bitset (operator>>): Likewise.
        * include/std/fstream (basic_filebuf::close): Remove throw() spec.
        * libsupc++/cxxabi-internal.h: Split out from...
        * libsupc++/cxxabi.h: ...here.

From-SVN: r124517

25 files changed:
gcc/testsuite/g++.dg/abi/forced.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/config/locale/gnu/monetary_members.cc
libstdc++-v3/include/bits/basic_string.tcc
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/bits/ostream.tcc
libstdc++-v3/include/bits/ostream_insert.h
libstdc++-v3/include/debug/deque
libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp
libstdc++-v3/include/ext/vstring.tcc
libstdc++-v3/include/std/bitset
libstdc++-v3/include/std/fstream
libstdc++-v3/include/tr1/hypergeometric.tcc
libstdc++-v3/libsupc++/cxxabi-internal.h [new file with mode: 0644]
libstdc++-v3/libsupc++/cxxabi.h
libstdc++-v3/libsupc++/eh_exception.cc
libstdc++-v3/libsupc++/eh_personality.cc
libstdc++-v3/src/compatibility.cc
libstdc++-v3/src/ios.cc
libstdc++-v3/src/ios_init.cc
libstdc++-v3/src/istream.cc

diff --git a/gcc/testsuite/g++.dg/abi/forced.C b/gcc/testsuite/g++.dg/abi/forced.C
new file mode 100644 (file)
index 0000000..7a9c359
--- /dev/null
@@ -0,0 +1,25 @@
+// This test only applies to glibc (NPTL) targets.
+// { dg-do run { target *-*-linux* } }
+// { dg-options "-pthread" }
+
+#include <pthread.h>
+#include <cxxabi.h>
+extern "C" int printf (const char *, ...);
+
+int main()
+{
+  try
+    {
+      pthread_exit (0);
+    }
+  catch (abi::__forced_unwind &)
+    {
+      printf ("caught forced unwind\n");
+      throw;
+    }
+  catch (...)
+    {
+      printf ("caught ...\n");
+      return 1;
+    }
+}
index daac60c..89e64b2 100644 (file)
@@ -1,3 +1,28 @@
+2007-05-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/28145
+       * libsupc++/cxxabi.h (__forced_unwind, __foreign_exception):
+       New classes.
+       * libsupc++/eh_exception.cc: Define their destructors.
+       * config/abi/pre/gnu.ver: Export their type_infos.
+       * config/abi/pre/gnu-versioned-namespace.ver: Likewise.
+       * libsupc++/eh_personality.cc: A handler for abi::__forced_unwind
+       matches a forced unwind, and a handler for abi::__foreign_exception
+       matches a foreign exception.
+       
+       * include/bits/istream.tcc: Rethrow forced unwind.
+       * include/bits/ostream.tcc: Likewise.
+       * include/bits/ostream_insert.h: Likewise.
+       * include/bits/basic_string.tcc (operator>>, getline): Likewise.
+       * include/bits/fstream.tcc (basic_filebuf::close): Likewise.
+       * include/ext/vstring.cc (operator>>, getline): Likewise.
+       * src/istream.cc: Likewise.
+       * src/compatibility.cc (basic_istream::ignore): Likewise.
+       * include/std/bitset (operator>>): Likewise.
+       * include/std/fstream (basic_filebuf::close): Remove throw() spec.
+       * libsupc++/cxxabi-internal.h: Split out from...
+       * libsupc++/cxxabi.h: ...here.
+
 2007-05-07  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/stl_algobase.h: Do not include <cstring>.
index 3b9b475..b3ebf82 100644 (file)
@@ -178,6 +178,8 @@ CXXABI_1.7 {
     _ZTIN10__cxxabiv119__pointer_type_infoE;
     _ZTIN10__cxxabiv120__si_class_type_infoE;
     _ZTIN10__cxxabiv121__vmi_class_type_infoE;
+    _ZTIN10__cxxabiv115__forced_unwindE;
+    _ZTIN10__cxxabiv119__foreign_exceptionE;
 
     # typeinfo name
     _ZTS[a-z];
index 1748f3a..729589c 100644 (file)
@@ -793,6 +793,8 @@ CXXABI_1.3 {
     _ZTIN10__cxxabiv119__pointer_type_infoE;
     _ZTIN10__cxxabiv120__si_class_type_infoE;
     _ZTIN10__cxxabiv121__vmi_class_type_infoE;
+    _ZTIN10__cxxabiv115__forced_unwindE;
+    _ZTIN10__cxxabiv119__foreign_exceptionE;
 
     # typeinfo name
     _ZTS[a-fh-z];
index b3cd05d..9a41774 100644 (file)
@@ -448,7 +448,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                _M_data->_M_curr_symbol = L"";
              _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
            }
-         catch (...)
+         catch(...)
            {
              delete _M_data;
              _M_data = 0;
@@ -591,7 +591,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                _M_data->_M_curr_symbol = L"";
               _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
            }
-          catch (...)
+          catch(...)
            {
              delete _M_data;
               _M_data = 0;
index 7483371..4c68293 100644 (file)
@@ -46,6 +46,8 @@
 
 #pragma GCC system_header
 
+#include <cxxabi-internal.h>
+
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template<typename _CharT, typename _Traits, typename _Alloc>
@@ -1015,6 +1017,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= __ios_base::eofbit;
              __in.width(0);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(__ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1074,6 +1081,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= __ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(__ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
index 54e75db..f9b84bf 100644 (file)
@@ -42,6 +42,8 @@
 
 #pragma GCC system_header
 
+#include <cxxabi-internal.h>
+
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template<typename _CharT, typename _Traits>
@@ -127,36 +129,51 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   template<typename _CharT, typename _Traits>
     typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
     basic_filebuf<_CharT, _Traits>::
-    close() throw()
+    close()
     {
-      __filebuf_type* __ret = NULL;
-      if (this->is_open())
+      if (!this->is_open())
+       return NULL;
+
+      bool __testfail = false;
+      {
+       // NB: Do this here so that re-opened filebufs will be cool...
+       struct __close_sentry
        {
-         bool __testfail = false;
-         try
-           {
-             if (!_M_terminate_output())
-               __testfail = true;
-           }
-         catch(...)
-           { __testfail = true; }
-
-         // NB: Do this here so that re-opened filebufs will be cool...
-         _M_mode = ios_base::openmode(0);
-         _M_pback_init = false;
-         _M_destroy_internal_buffer();
-         _M_reading = false;
-         _M_writing = false;
-         _M_set_buffer(-1);
-         _M_state_last = _M_state_cur = _M_state_beg;
-
-         if (!_M_file.close())
-           __testfail = true;
-
-         if (!__testfail)
-           __ret = this;
-       }
-      return __ret;
+         basic_filebuf *__fb;
+         __close_sentry (basic_filebuf *__fbi): __fb(__fbi) { }
+         ~__close_sentry ()
+         {
+           __fb->_M_mode = ios_base::openmode(0);
+           __fb->_M_pback_init = false;
+           __fb->_M_destroy_internal_buffer();
+           __fb->_M_reading = false;
+           __fb->_M_writing = false;
+           __fb->_M_set_buffer(-1);
+           __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
+         }
+       } __cs (this);
+
+       try
+         {
+           if (!_M_terminate_output())
+             __testfail = true;
+         }
+       catch(__cxxabiv1::__forced_unwind&)
+         {
+           _M_file.close();
+           __throw_exception_again;
+         }
+       catch(...)
+         { __testfail = true; }
+      }
+
+      if (!_M_file.close())
+       __testfail = true;
+
+      if (__testfail)
+       return NULL;
+      else
+       return this;
     }
 
   template<typename _CharT, typename _Traits>
index 4588b9c..e6b18cd 100644 (file)
@@ -43,6 +43,8 @@
 
 #pragma GCC system_header
 
+#include <cxxabi-internal.h>
+
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template<typename _CharT, typename _Traits>
@@ -98,6 +100,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                const __num_get_type& __ng = __check_facet(this->_M_num_get);
                __ng.get(*this, 0, *this, __err, __v);
              }
+           catch(__cxxabiv1::__forced_unwind&)
+             {
+               this->_M_setstate(ios_base::badbit);            
+               __throw_exception_again;
+             }
            catch(...)
              { this->_M_setstate(ios_base::badbit); }
            if (__err)
@@ -163,6 +170,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (__ineof)
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::failbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::failbit); }
        }
@@ -194,6 +206,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
@@ -226,6 +243,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
@@ -264,6 +286,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
@@ -307,6 +334,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
@@ -355,6 +387,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                     __err |= ios_base::failbit;
                 }
             }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
           catch(...)
             { this->_M_setstate(ios_base::badbit); }
         }
@@ -392,6 +429,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                _M_gcount = 1;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -449,6 +491,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__c, __eof))
                 __err |= ios_base::eofbit;
             }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
           catch(...)
             { this->_M_setstate(ios_base::badbit); }
           if (__err)
@@ -509,6 +556,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                  __sb->sbumpc();
                }
             }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
           catch(...)
             { this->_M_setstate(ios_base::badbit); }
           if (__err)
@@ -534,6 +586,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__c, traits_type::eof()))
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -558,6 +615,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (_M_gcount != __n)
                __err |= (ios_base::eofbit | ios_base::failbit);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -585,6 +647,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else if (__num == -1)
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -613,6 +680,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                  || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
                __err |= ios_base::badbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -641,6 +713,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                  || traits_type::eq_int_type(__sb->sungetc(), __eof))
                __err |= ios_base::badbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -672,6 +749,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                    __ret = 0;
                }
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -694,6 +776,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
            __ret = this->rdbuf()->pubseekoff(0, ios_base::cur,
                                              ios_base::in);
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       return __ret;
@@ -720,6 +807,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= ios_base::failbit;
            }
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       if (__err)
@@ -748,6 +840,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= ios_base::failbit;
            }
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       if (__err)
@@ -775,6 +872,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= (ios_base::eofbit | ios_base::failbit);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { __in._M_setstate(ios_base::badbit); }
          if (__err)
@@ -828,6 +930,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              *__s = char_type();
              __in.width(0);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { __in._M_setstate(ios_base::badbit); }
        }
index 141f44c..5e6a810 100644 (file)
@@ -409,7 +409,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        {
          try
            { delete this; }
-         catch (...)
+         catch(...)
            { }
        }
     }
index 8ef9d89..4691c64 100644 (file)
@@ -43,6 +43,8 @@
 
 #pragma GCC system_header
 
+#include <cxxabi-internal.h>
+
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template<typename _CharT, typename _Traits>
@@ -76,6 +78,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                if (__np.put(*this, *this, this->fill(), __v).failed())
                  __err |= ios_base::badbit;
              }
+           catch(__cxxabiv1::__forced_unwind&)
+             {
+               this->_M_setstate(ios_base::badbit);            
+               __throw_exception_again;
+             }
            catch(...)
              { this->_M_setstate(ios_base::badbit); }
            if (__err)
@@ -126,6 +133,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (!__copy_streambufs(__sbin, this->rdbuf()))
                __err |= ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);              
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::failbit); }
        }
@@ -157,7 +169,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__put, traits_type::eof()))
                __err |= ios_base::badbit;
            }
-         catch (...)
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);              
+             __throw_exception_again;
+           }
+         catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
            this->setstate(__err);
@@ -182,7 +199,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        {
          try
            { _M_write(__s, __n); }
-         catch (...)
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);              
+             __throw_exception_again;
+           }
+         catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
       return *this;
@@ -202,6 +224,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
          if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
            __err |= ios_base::badbit;
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);          
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       if (__err)
@@ -220,6 +247,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
          if (!this->fail())
            __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);          
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       return __ret;
@@ -245,6 +277,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= ios_base::failbit;
            }
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);          
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       if (__err)
@@ -272,6 +309,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= ios_base::failbit;
            }
        }
+      catch(__cxxabiv1::__forced_unwind&)
+       {
+         this->_M_setstate(ios_base::badbit);          
+         __throw_exception_again;
+       }
       catch(...)
        { this->_M_setstate(ios_base::badbit); }
       if (__err)
@@ -289,31 +331,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        {
          // _GLIBCXX_RESOLVE_LIB_DEFECTS
          // 167.  Improper use of traits_type::length()
-         const size_t __clen = char_traits<char>::length(__s);      
-         _CharT* __ws = 0;
+         const size_t __clen = char_traits<char>::length(__s);
          try
-           { 
-             __ws = new _CharT[__clen];
-             for (size_t  __i = 0; __i < __clen; ++__i)
-               __ws[__i] = __out.widen(__s[__i]);
-           }
-         catch(...)
            {
-             delete [] __ws;
-             __out._M_setstate(ios_base::badbit);
-             return __out;
-           }
+             struct __ptr_guard
+             {
+               _CharT *p;
+               __ptr_guard (_CharT *ip): p(ip) { }
+               ~__ptr_guard() { delete[] p; }
+               _CharT* __get() { return p; }
+             } __pg (new _CharT[__clen]);
 
-         try
-           {
+             _CharT *__ws = __pg.__get();
+             for (size_t  __i = 0; __i < __clen; ++__i)
+               __ws[__i] = __out.widen(__s[__i]);
              __ostream_insert(__out, __ws, __clen);
-             delete [] __ws;
            }
-         catch(...)
+         catch(__cxxabiv1::__forced_unwind&)
            {
-             delete [] __ws;
+             __out._M_setstate(ios_base::badbit);
              __throw_exception_again;
            }
+         catch(...)
+           { __out._M_setstate(ios_base::badbit); }
        }
       return __out;
     }
index e9e83fb..5815de9 100644 (file)
@@ -38,6 +38,7 @@
 #pragma GCC system_header
 
 #include <iosfwd>
+#include <cxxabi-internal.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
@@ -103,6 +104,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __ostream_write(__out, __s, __n);
              __out.width(0);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __out._M_setstate(__ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { __out._M_setstate(__ios_base::badbit); }
        }
index 79142d9..6e523b8 100644 (file)
@@ -313,7 +313,7 @@ namespace __debug
                return iterator(_Base::erase(__first.base(), __last.base()),
                                this);
              }
-           catch (...)
+           catch(...)
              {
                this->_M_revalidate_singular();
                __throw_exception_again;
index aa29e07..9c67375 100644 (file)
@@ -265,7 +265,7 @@ set_loads(std::pair<float, float> load_pair)
       m_load_max = load_pair.second;
       do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2)));
     }
-  catch (...)
+  catch(...)
     {
       m_load_min = old_load_min;
       m_load_max = old_load_max;
index 7d03017..7f3478a 100644 (file)
@@ -38,6 +38,8 @@
 
 #pragma GCC system_header
 
+#include <cxxabi-internal.h>
+
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 
   template<typename _CharT, typename _Traits, typename _Alloc,
@@ -598,6 +600,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= __ios_base::eofbit;
              __in.width(0);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(__ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -669,6 +676,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= __ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(__ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
index 9c869bf..09f05e1 100644 (file)
@@ -56,6 +56,7 @@
 #include <bits/functexcept.h>   // For invalid_argument, out_of_range,
                                 // overflow_error
 #include <iosfwd>
+#include <cxxabi-internal.h>
 
 #define _GLIBCXX_BITSET_BITS_PER_WORD  (__CHAR_BIT__ * sizeof(unsigned long))
 #define _GLIBCXX_BITSET_WORDS(__n) \
@@ -1271,6 +1272,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
                    }
                }
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __is._M_setstate(__ios_base::badbit);             
+             __throw_exception_again;
+           }
          catch(...)
            { __is._M_setstate(__ios_base::badbit); }
        }
index cab18c1..18c24be 100644 (file)
@@ -275,7 +275,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        *  If any operations fail, this function also fails.
       */
       __filebuf_type*
-      close() throw();
+      close();
 
     protected:
       void
index d54e6fe..c0d676f 100644 (file)
@@ -613,7 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
               __sgn_g1cb = __log_gamma_sign(__c - __b);
               __ln_g1cb = __log_gamma(__c - __b);
             }
-          catch (...)
+          catch(...)
             {
               __ok1 = false;
             }
@@ -628,7 +628,7 @@ _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
               __sgn_g2b = __log_gamma_sign(__b);
               __ln_g2b = __log_gamma(__b);
             }
-          catch (...)
+          catch(...)
             {
               __ok2 = false;
             }
diff --git a/libstdc++-v3/libsupc++/cxxabi-internal.h b/libstdc++-v3/libsupc++/cxxabi-internal.h
new file mode 100644 (file)
index 0000000..755c0a4
--- /dev/null
@@ -0,0 +1,555 @@
+// new abi support -*- C++ -*-
+  
+// Copyright (C) 2000, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+// 
+// GCC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
+/* This file declares the new abi entry points into the runtime. It is not
+   normally necessary for user programs to include this header, or use the
+   entry points directly. However, this header is available should that be
+   needed.
+   
+   Some of the entry points are intended for both C and C++, thus this header
+   is includable from both C and C++. Though the C++ specific parts are not
+   available in C, naturally enough.  */
+
+/** @file cxxabi.h
+ *  The header provides an interface to the C++ ABI.
+ */
+
+#ifndef _CXXABI_INTERNAL_H
+#define _CXXABI_INTERNAL_H 1
+
+#pragma GCC visibility push(default)
+
+#include <stddef.h>
+#include <bits/cxxabi_tweaks.h>
+#ifdef __cplusplus
+namespace __cxxabiv1
+{  
+  extern "C" 
+  {
+#endif
+
+  typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *);
+
+  // Allocate array.
+  void* 
+  __cxa_vec_new(size_t __element_count, size_t __element_size, 
+               size_t __padding_size, __cxa_cdtor_type constructor,
+               __cxa_cdtor_type destructor);
+
+  void*
+  __cxa_vec_new2(size_t __element_count, size_t __element_size,
+                size_t __padding_size, __cxa_cdtor_type constructor,
+                __cxa_cdtor_type destructor, void *(*__alloc) (size_t), 
+                void (*__dealloc) (void*));
+
+  void*
+  __cxa_vec_new3(size_t __element_count, size_t __element_size,
+                size_t __padding_size, __cxa_cdtor_type constructor,
+                __cxa_cdtor_type destructor, void *(*__alloc) (size_t), 
+                void (*__dealloc) (void*, size_t));
+
+  // Construct array.
+  __cxa_vec_ctor_return_type
+  __cxa_vec_ctor(void* __array_address, size_t __element_count,
+                size_t __element_size, __cxa_cdtor_type constructor,
+                __cxa_cdtor_type destructor);
+
+  __cxa_vec_ctor_return_type
+  __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count, 
+                 size_t element_size, 
+                 __cxa_cdtor_return_type (*constructor) (void*, void*), 
+                 __cxa_cdtor_type destructor);
+  // Destruct array.
+  void 
+  __cxa_vec_dtor(void* __array_address, size_t __element_count,
+                size_t __element_size, __cxa_cdtor_type destructor);
+  
+  void 
+  __cxa_vec_cleanup(void* __array_address, size_t __element_count,
+                   size_t __element_size, __cxa_cdtor_type destructor);
+  
+  // Destruct and release array.
+  void 
+  __cxa_vec_delete(void* __array_address, size_t __element_size,
+                  size_t __padding_size, __cxa_cdtor_type destructor);
+
+  void 
+  __cxa_vec_delete2(void* __array_address, size_t __element_size,
+                   size_t __padding_size, __cxa_cdtor_type destructor,
+                   void (*__dealloc) (void*));
+                  
+  void 
+  __cxa_vec_delete3(void* __array_address, size_t __element_size,
+                   size_t __padding_size, __cxa_cdtor_type destructor,
+                   void (*__dealloc) (void*, size_t));
+
+  int 
+  __cxa_guard_acquire(__guard*);
+
+  void 
+  __cxa_guard_release(__guard*);
+
+  void 
+  __cxa_guard_abort(__guard*);
+
+  // Pure virtual functions.
+  void
+  __cxa_pure_virtual(void);
+
+  // Exception handling.
+  void
+  __cxa_bad_cast();
+
+  void
+  __cxa_bad_typeid();
+
+  // DSO destruction.
+  int
+  __cxa_atexit(void (*)(void*), void*, void*)
+#ifdef __cplusplus
+    throw ()
+#endif
+    ;
+
+  int
+  __cxa_finalize(void*);
+
+  // Demangling routines. 
+  char*
+  __cxa_demangle(const char* __mangled_name, char* __output_buffer,
+                size_t* __length, int* __status);
+#ifdef __cplusplus
+  }
+} // namespace __cxxabiv1
+#endif
+
+#ifdef __cplusplus
+
+#include <typeinfo>
+
+namespace __cxxabiv1
+{
+  // Type information for int, float etc.
+  class __fundamental_type_info : public std::type_info
+  {
+  public:
+    explicit 
+    __fundamental_type_info(const char* __n) : std::type_info(__n) { }
+
+    virtual 
+    ~__fundamental_type_info();
+  };
+
+  // Type information for array objects.
+  class __array_type_info : public std::type_info
+  {
+  public:
+    explicit 
+    __array_type_info(const char* __n) : std::type_info(__n) { }
+
+    virtual 
+    ~__array_type_info();
+  };
+
+  // Type information for functions (both member and non-member).
+  class __function_type_info : public std::type_info
+  {
+  public:
+    explicit 
+    __function_type_info(const char* __n) : std::type_info(__n) { }
+
+    virtual 
+    ~__function_type_info();
+
+  protected:
+    // Implementation defined member function.
+    virtual bool 
+    __is_function_p() const;
+  };
+
+  // Type information for enumerations.
+  class __enum_type_info : public std::type_info
+  {
+  public:
+    explicit 
+    __enum_type_info(const char* __n) : std::type_info(__n) { }
+
+    virtual 
+    ~__enum_type_info();
+  };
+
+  // Common type information for simple pointers and pointers to member.
+  class __pbase_type_info : public std::type_info
+  {
+  public:
+    unsigned int               __flags; // Qualification of the target object.
+    const std::type_info*      __pointee; // Type of pointed to object.
+
+    explicit 
+    __pbase_type_info(const char* __n, int __quals, 
+                     const std::type_info* __type)
+    : std::type_info(__n), __flags(__quals), __pointee(__type)
+    { }
+    
+    virtual 
+    ~__pbase_type_info();
+
+    // Implementation defined type.
+    enum __masks 
+      {
+       __const_mask = 0x1,
+       __volatile_mask = 0x2,
+       __restrict_mask = 0x4,
+       __incomplete_mask = 0x8,
+       __incomplete_class_mask = 0x10
+      };
+
+  protected:
+    __pbase_type_info(const __pbase_type_info&);
+
+    __pbase_type_info&
+    operator=(const __pbase_type_info&);
+
+    // Implementation defined member functions.
+    virtual bool 
+    __do_catch(const std::type_info* __thr_type, void** __thr_obj, 
+              unsigned int __outer) const;
+
+    inline virtual bool 
+    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
+                   unsigned __outer) const;
+  };
+
+  // Type information for simple pointers.
+  class __pointer_type_info : public __pbase_type_info
+  {
+  public:
+    explicit 
+    __pointer_type_info(const char* __n, int __quals, 
+                       const std::type_info* __type)
+    : __pbase_type_info (__n, __quals, __type) { }
+
+
+    virtual 
+    ~__pointer_type_info();
+
+  protected:
+    // Implementation defined member functions.
+    virtual bool 
+    __is_pointer_p() const;
+
+    virtual bool 
+    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, 
+                   unsigned __outer) const;
+  };
+
+  class __class_type_info;
+
+  // Type information for a pointer to member variable.
+  class __pointer_to_member_type_info : public __pbase_type_info
+  {
+  public:
+    __class_type_info* __context;   // Class of the member.
+
+    explicit 
+    __pointer_to_member_type_info(const char* __n, int __quals,
+                                 const std::type_info* __type, 
+                                 __class_type_info* __klass)
+    : __pbase_type_info(__n, __quals, __type), __context(__klass) { }
+
+    virtual 
+    ~__pointer_to_member_type_info();
+
+  protected:
+    __pointer_to_member_type_info(const __pointer_to_member_type_info&);
+
+    __pointer_to_member_type_info&
+    operator=(const __pointer_to_member_type_info&);
+
+    // Implementation defined member function.
+    virtual bool 
+    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
+                   unsigned __outer) const;
+  };
+
+  // Helper class for __vmi_class_type.
+  class __base_class_type_info
+  {
+  public:
+    const __class_type_info*   __base_type;  // Base class type.
+    long                       __offset_flags;  // Offset and info.
+
+    enum __offset_flags_masks 
+      {
+       __virtual_mask = 0x1,
+       __public_mask = 0x2,
+       __hwm_bit = 2,
+       __offset_shift = 8          // Bits to shift offset.
+      };
+  
+    // Implementation defined member functions.
+    bool 
+    __is_virtual_p() const
+    { return __offset_flags & __virtual_mask; }
+
+    bool 
+    __is_public_p() const
+    { return __offset_flags & __public_mask; }
+
+    ptrdiff_t 
+    __offset() const
+    { 
+      // This shift, being of a signed type, is implementation
+      // defined. GCC implements such shifts as arithmetic, which is
+      // what we want.
+      return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift;
+    }
+  };
+
+  // Type information for a class.
+  class __class_type_info : public std::type_info
+  {
+  public:
+    explicit 
+    __class_type_info (const char *__n) : type_info(__n) { }
+
+    virtual 
+    ~__class_type_info ();
+
+    // Implementation defined types.
+    // The type sub_kind tells us about how a base object is contained
+    // within a derived object. We often do this lazily, hence the
+    // UNKNOWN value. At other times we may use NOT_CONTAINED to mean
+    // not publicly contained.
+    enum __sub_kind
+      {
+       // We have no idea.
+       __unknown = 0, 
+
+       // Not contained within us (in some circumstances this might
+       // mean not contained publicly)
+       __not_contained, 
+
+       // Contained ambiguously.
+       __contained_ambig, 
+    
+       // Via a virtual path.
+       __contained_virtual_mask = __base_class_type_info::__virtual_mask, 
+
+       // Via a public path.
+       __contained_public_mask = __base_class_type_info::__public_mask,   
+
+       // Contained within us.
+       __contained_mask = 1 << __base_class_type_info::__hwm_bit,
+    
+       __contained_private = __contained_mask,
+       __contained_public = __contained_mask | __contained_public_mask
+      };
+
+    struct __upcast_result;
+    struct __dyncast_result;
+
+  protected:
+    // Implementation defined member functions.
+    virtual bool 
+    __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const;
+
+    virtual bool 
+    __do_catch(const type_info* __thr_type, void** __thr_obj, 
+              unsigned __outer) const;
+
+  public:
+    // Helper for upcast. See if DST is us, or one of our bases. 
+    // Return false if not found, true if found. 
+    virtual bool 
+    __do_upcast(const __class_type_info* __dst, const void* __obj,
+               __upcast_result& __restrict __result) const;
+
+    // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly
+    // within OBJ_PTR. OBJ_PTR points to a base object of our type,
+    // which is the destination type. SRC2DST indicates how SRC
+    // objects might be contained within this type.  If SRC_PTR is one
+    // of our SRC_TYPE bases, indicate the virtuality. Returns
+    // not_contained for non containment or private containment.
+    inline __sub_kind 
+    __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
+                     const __class_type_info* __src_type, 
+                     const void* __src_ptr) const;
+
+    // Helper for dynamic cast. ACCESS_PATH gives the access from the
+    // most derived object to this base. DST_TYPE indicates the
+    // desired type we want. OBJ_PTR points to a base of our type
+    // within the complete object. SRC_TYPE indicates the static type
+    // started from and SRC_PTR points to that base within the most
+    // derived object. Fill in RESULT with what we find. Return true
+    // if we have located an ambiguous match.
+    virtual bool 
+    __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
+                const __class_type_info* __dst_type, const void* __obj_ptr, 
+                const __class_type_info* __src_type, const void* __src_ptr, 
+                __dyncast_result& __result) const;
+    
+    // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE
+    // bases are inherited by the type started from -- which is not
+    // necessarily the current type. The current type will be a base
+    // of the destination type.  OBJ_PTR points to the current base.
+    virtual __sub_kind 
+    __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
+                        const __class_type_info* __src_type,
+                        const void* __src_ptr) const;
+  };
+
+  // Type information for a class with a single non-virtual base.
+  class __si_class_type_info : public __class_type_info
+  {
+  public:
+    const __class_type_info* __base_type;
+
+    explicit 
+    __si_class_type_info(const char *__n, const __class_type_info *__base)
+    : __class_type_info(__n), __base_type(__base) { }
+
+    virtual 
+    ~__si_class_type_info();
+
+  protected:
+    __si_class_type_info(const __si_class_type_info&);
+
+    __si_class_type_info&
+    operator=(const __si_class_type_info&);
+
+    // Implementation defined member functions.
+    virtual bool 
+    __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
+                const __class_type_info* __dst_type, const void* __obj_ptr,
+                const __class_type_info* __src_type, const void* __src_ptr,
+                __dyncast_result& __result) const;
+
+    virtual __sub_kind 
+    __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
+                        const __class_type_info* __src_type,
+                        const void* __sub_ptr) const;
+
+    virtual bool 
+    __do_upcast(const __class_type_info*__dst, const void*__obj,
+               __upcast_result& __restrict __result) const;
+  };
+
+  // Type information for a class with multiple and/or virtual bases.
+  class __vmi_class_type_info : public __class_type_info 
+  {
+  public:
+    unsigned int               __flags;  // Details about the class hierarchy.
+    unsigned int               __base_count;  // Number of direct bases.
+
+    // The array of bases uses the trailing array struct hack so this
+    // class is not constructable with a normal constructor. It is
+    // internally generated by the compiler.
+    __base_class_type_info     __base_info[1];  // Array of bases.
+
+    explicit 
+    __vmi_class_type_info(const char* __n, int ___flags)
+    : __class_type_info(__n), __flags(___flags), __base_count(0) { }
+
+    virtual 
+    ~__vmi_class_type_info();
+
+    // Implementation defined types.
+    enum __flags_masks 
+      {
+       __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base.
+       __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance.
+       __flags_unknown_mask = 0x10
+      };
+
+  protected:
+    // Implementation defined member functions.
+    virtual bool 
+    __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
+                const __class_type_info* __dst_type, const void* __obj_ptr,
+                const __class_type_info* __src_type, const void* __src_ptr,
+                __dyncast_result& __result) const;
+
+    virtual __sub_kind 
+    __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, 
+                        const __class_type_info* __src_type,
+                        const void* __src_ptr) const;
+    
+    virtual bool 
+    __do_upcast(const __class_type_info* __dst, const void* __obj,
+               __upcast_result& __restrict __result) const;
+  };
+
+  // Dynamic cast runtime.
+  // src2dst has the following possible values
+  //  >-1: src_type is a unique public non-virtual base of dst_type
+  //       dst_ptr + src2dst == src_ptr
+  //   -1: unspecified relationship
+  //   -2: src_type is not a public base of dst_type
+  //   -3: src_type is a multiple public non-virtual base of dst_type
+  extern "C" void*
+  __dynamic_cast(const void* __src_ptr, // Starting object.
+                const __class_type_info* __src_type, // Static type of object.
+                const __class_type_info* __dst_type, // Desired target type.
+                ptrdiff_t __src2dst); // How src and dst are related.
+
+
+  // Returns the type_info for the currently handled exception [15.3/8], or
+  // null if there is none.
+  extern "C" std::type_info*
+  __cxa_current_exception_type();
+
+  // A magic placeholder class that can be caught by reference
+  // to recognize forced unwinding.
+  class __forced_unwind
+  {
+    virtual ~__forced_unwind() throw();
+    virtual void __pure() = 0; // prevent catch by value
+  };
+
+  // A magic placeholder class that can be caught by reference
+  // to recognize foreign exceptions.
+  class __foreign_exception
+  {
+    virtual ~__foreign_exception() throw();
+    virtual void __pure() = 0; // prevent catch by value
+  };
+
+} // namespace __cxxabiv1
+
+#endif // __cplusplus
+
+#pragma GCC visibility pop
+
+#endif // __CXXABI_INTERNAL_H 
index 9e8a910..184eff6 100644 (file)
 
 #pragma GCC visibility push(default)
 
-#include <stddef.h>
-#include <bits/cxxabi_tweaks.h>
+#include <cxxabi-internal.h>
  
 #ifdef __cplusplus
-namespace __cxxabiv1
-{  
-  extern "C" 
-  {
-#endif
-
-  typedef __cxa_cdtor_return_type (*__cxa_cdtor_type)(void *);
-
-  // Allocate array.
-  void* 
-  __cxa_vec_new(size_t __element_count, size_t __element_size, 
-               size_t __padding_size, __cxa_cdtor_type constructor,
-               __cxa_cdtor_type destructor);
-
-  void*
-  __cxa_vec_new2(size_t __element_count, size_t __element_size,
-                size_t __padding_size, __cxa_cdtor_type constructor,
-                __cxa_cdtor_type destructor, void *(*__alloc) (size_t), 
-                void (*__dealloc) (void*));
-
-  void*
-  __cxa_vec_new3(size_t __element_count, size_t __element_size,
-                size_t __padding_size, __cxa_cdtor_type constructor,
-                __cxa_cdtor_type destructor, void *(*__alloc) (size_t), 
-                void (*__dealloc) (void*, size_t));
-
-  // Construct array.
-  __cxa_vec_ctor_return_type
-  __cxa_vec_ctor(void* __array_address, size_t __element_count,
-                size_t __element_size, __cxa_cdtor_type constructor,
-                __cxa_cdtor_type destructor);
-
-  __cxa_vec_ctor_return_type
-  __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count, 
-                 size_t element_size, 
-                 __cxa_cdtor_return_type (*constructor) (void*, void*), 
-                 __cxa_cdtor_type destructor);
-  // Destruct array.
-  void 
-  __cxa_vec_dtor(void* __array_address, size_t __element_count,
-                size_t __element_size, __cxa_cdtor_type destructor);
-  
-  void 
-  __cxa_vec_cleanup(void* __array_address, size_t __element_count,
-                   size_t __element_size, __cxa_cdtor_type destructor);
-  
-  // Destruct and release array.
-  void 
-  __cxa_vec_delete(void* __array_address, size_t __element_size,
-                  size_t __padding_size, __cxa_cdtor_type destructor);
-
-  void 
-  __cxa_vec_delete2(void* __array_address, size_t __element_size,
-                   size_t __padding_size, __cxa_cdtor_type destructor,
-                   void (*__dealloc) (void*));
-                  
-  void 
-  __cxa_vec_delete3(void* __array_address, size_t __element_size,
-                   size_t __padding_size, __cxa_cdtor_type destructor,
-                   void (*__dealloc) (void*, size_t));
-
-  int 
-  __cxa_guard_acquire(__guard*);
-
-  void 
-  __cxa_guard_release(__guard*);
-
-  void 
-  __cxa_guard_abort(__guard*);
-
-  // Pure virtual functions.
-  void
-  __cxa_pure_virtual(void);
-
-  // Exception handling.
-  void
-  __cxa_bad_cast();
-
-  void
-  __cxa_bad_typeid();
-
-  // DSO destruction.
-  int
-  __cxa_atexit(void (*)(void*), void*, void*)
-#ifdef __cplusplus
-    throw ()
-#endif
-    ;
-
-  int
-  __cxa_finalize(void*);
-
-  // Demangling routines. 
-  char*
-  __cxa_demangle(const char* __mangled_name, char* __output_buffer,
-                size_t* __length, int* __status);
-#ifdef __cplusplus
-  }
-} // namespace __cxxabiv1
-#endif
-
-#ifdef __cplusplus
-
-#include <typeinfo>
-
-namespace __cxxabiv1
-{
-  // Type information for int, float etc.
-  class __fundamental_type_info : public std::type_info
-  {
-  public:
-    explicit 
-    __fundamental_type_info(const char* __n) : std::type_info(__n) { }
-
-    virtual 
-    ~__fundamental_type_info();
-  };
-
-  // Type information for array objects.
-  class __array_type_info : public std::type_info
-  {
-  public:
-    explicit 
-    __array_type_info(const char* __n) : std::type_info(__n) { }
-
-    virtual 
-    ~__array_type_info();
-  };
-
-  // Type information for functions (both member and non-member).
-  class __function_type_info : public std::type_info
-  {
-  public:
-    explicit 
-    __function_type_info(const char* __n) : std::type_info(__n) { }
-
-    virtual 
-    ~__function_type_info();
-
-  protected:
-    // Implementation defined member function.
-    virtual bool 
-    __is_function_p() const;
-  };
-
-  // Type information for enumerations.
-  class __enum_type_info : public std::type_info
-  {
-  public:
-    explicit 
-    __enum_type_info(const char* __n) : std::type_info(__n) { }
-
-    virtual 
-    ~__enum_type_info();
-  };
-
-  // Common type information for simple pointers and pointers to member.
-  class __pbase_type_info : public std::type_info
-  {
-  public:
-    unsigned int               __flags; // Qualification of the target object.
-    const std::type_info*      __pointee; // Type of pointed to object.
-
-    explicit 
-    __pbase_type_info(const char* __n, int __quals, 
-                     const std::type_info* __type)
-    : std::type_info(__n), __flags(__quals), __pointee(__type)
-    { }
-    
-    virtual 
-    ~__pbase_type_info();
-
-    // Implementation defined type.
-    enum __masks 
-      {
-       __const_mask = 0x1,
-       __volatile_mask = 0x2,
-       __restrict_mask = 0x4,
-       __incomplete_mask = 0x8,
-       __incomplete_class_mask = 0x10
-      };
-
-  protected:
-    __pbase_type_info(const __pbase_type_info&);
-
-    __pbase_type_info&
-    operator=(const __pbase_type_info&);
-
-    // Implementation defined member functions.
-    virtual bool 
-    __do_catch(const std::type_info* __thr_type, void** __thr_obj, 
-              unsigned int __outer) const;
-
-    inline virtual bool 
-    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
-                   unsigned __outer) const;
-  };
-
-  // Type information for simple pointers.
-  class __pointer_type_info : public __pbase_type_info
-  {
-  public:
-    explicit 
-    __pointer_type_info(const char* __n, int __quals, 
-                       const std::type_info* __type)
-    : __pbase_type_info (__n, __quals, __type) { }
-
-
-    virtual 
-    ~__pointer_type_info();
-
-  protected:
-    // Implementation defined member functions.
-    virtual bool 
-    __is_pointer_p() const;
-
-    virtual bool 
-    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, 
-                   unsigned __outer) const;
-  };
-
-  class __class_type_info;
-
-  // Type information for a pointer to member variable.
-  class __pointer_to_member_type_info : public __pbase_type_info
-  {
-  public:
-    __class_type_info* __context;   // Class of the member.
-
-    explicit 
-    __pointer_to_member_type_info(const char* __n, int __quals,
-                                 const std::type_info* __type, 
-                                 __class_type_info* __klass)
-    : __pbase_type_info(__n, __quals, __type), __context(__klass) { }
-
-    virtual 
-    ~__pointer_to_member_type_info();
-
-  protected:
-    __pointer_to_member_type_info(const __pointer_to_member_type_info&);
-
-    __pointer_to_member_type_info&
-    operator=(const __pointer_to_member_type_info&);
-
-    // Implementation defined member function.
-    virtual bool 
-    __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj,
-                   unsigned __outer) const;
-  };
-
-  // Helper class for __vmi_class_type.
-  class __base_class_type_info
-  {
-  public:
-    const __class_type_info*   __base_type;  // Base class type.
-    long                       __offset_flags;  // Offset and info.
-
-    enum __offset_flags_masks 
-      {
-       __virtual_mask = 0x1,
-       __public_mask = 0x2,
-       __hwm_bit = 2,
-       __offset_shift = 8          // Bits to shift offset.
-      };
-  
-    // Implementation defined member functions.
-    bool 
-    __is_virtual_p() const
-    { return __offset_flags & __virtual_mask; }
-
-    bool 
-    __is_public_p() const
-    { return __offset_flags & __public_mask; }
-
-    ptrdiff_t 
-    __offset() const
-    { 
-      // This shift, being of a signed type, is implementation
-      // defined. GCC implements such shifts as arithmetic, which is
-      // what we want.
-      return static_cast<ptrdiff_t>(__offset_flags) >> __offset_shift;
-    }
-  };
-
-  // Type information for a class.
-  class __class_type_info : public std::type_info
-  {
-  public:
-    explicit 
-    __class_type_info (const char *__n) : type_info(__n) { }
-
-    virtual 
-    ~__class_type_info ();
-
-    // Implementation defined types.
-    // The type sub_kind tells us about how a base object is contained
-    // within a derived object. We often do this lazily, hence the
-    // UNKNOWN value. At other times we may use NOT_CONTAINED to mean
-    // not publicly contained.
-    enum __sub_kind
-      {
-       // We have no idea.
-       __unknown = 0, 
-
-       // Not contained within us (in some circumstances this might
-       // mean not contained publicly)
-       __not_contained, 
-
-       // Contained ambiguously.
-       __contained_ambig, 
-    
-       // Via a virtual path.
-       __contained_virtual_mask = __base_class_type_info::__virtual_mask, 
-
-       // Via a public path.
-       __contained_public_mask = __base_class_type_info::__public_mask,   
-
-       // Contained within us.
-       __contained_mask = 1 << __base_class_type_info::__hwm_bit,
-    
-       __contained_private = __contained_mask,
-       __contained_public = __contained_mask | __contained_public_mask
-      };
-
-    struct __upcast_result;
-    struct __dyncast_result;
-
-  protected:
-    // Implementation defined member functions.
-    virtual bool 
-    __do_upcast(const __class_type_info* __dst_type, void**__obj_ptr) const;
-
-    virtual bool 
-    __do_catch(const type_info* __thr_type, void** __thr_obj, 
-              unsigned __outer) const;
-
-  public:
-    // Helper for upcast. See if DST is us, or one of our bases. 
-    // Return false if not found, true if found. 
-    virtual bool 
-    __do_upcast(const __class_type_info* __dst, const void* __obj,
-               __upcast_result& __restrict __result) const;
-
-    // Indicate whether SRC_PTR of type SRC_TYPE is contained publicly
-    // within OBJ_PTR. OBJ_PTR points to a base object of our type,
-    // which is the destination type. SRC2DST indicates how SRC
-    // objects might be contained within this type.  If SRC_PTR is one
-    // of our SRC_TYPE bases, indicate the virtuality. Returns
-    // not_contained for non containment or private containment.
-    inline __sub_kind 
-    __find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
-                     const __class_type_info* __src_type, 
-                     const void* __src_ptr) const;
-
-    // Helper for dynamic cast. ACCESS_PATH gives the access from the
-    // most derived object to this base. DST_TYPE indicates the
-    // desired type we want. OBJ_PTR points to a base of our type
-    // within the complete object. SRC_TYPE indicates the static type
-    // started from and SRC_PTR points to that base within the most
-    // derived object. Fill in RESULT with what we find. Return true
-    // if we have located an ambiguous match.
-    virtual bool 
-    __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
-                const __class_type_info* __dst_type, const void* __obj_ptr, 
-                const __class_type_info* __src_type, const void* __src_ptr, 
-                __dyncast_result& __result) const;
-    
-    // Helper for find_public_subobj. SRC2DST indicates how SRC_TYPE
-    // bases are inherited by the type started from -- which is not
-    // necessarily the current type. The current type will be a base
-    // of the destination type.  OBJ_PTR points to the current base.
-    virtual __sub_kind 
-    __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
-                        const __class_type_info* __src_type,
-                        const void* __src_ptr) const;
-  };
-
-  // Type information for a class with a single non-virtual base.
-  class __si_class_type_info : public __class_type_info
-  {
-  public:
-    const __class_type_info* __base_type;
-
-    explicit 
-    __si_class_type_info(const char *__n, const __class_type_info *__base)
-    : __class_type_info(__n), __base_type(__base) { }
-
-    virtual 
-    ~__si_class_type_info();
-
-  protected:
-    __si_class_type_info(const __si_class_type_info&);
-
-    __si_class_type_info&
-    operator=(const __si_class_type_info&);
-
-    // Implementation defined member functions.
-    virtual bool 
-    __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
-                const __class_type_info* __dst_type, const void* __obj_ptr,
-                const __class_type_info* __src_type, const void* __src_ptr,
-                __dyncast_result& __result) const;
-
-    virtual __sub_kind 
-    __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr,
-                        const __class_type_info* __src_type,
-                        const void* __sub_ptr) const;
-
-    virtual bool 
-    __do_upcast(const __class_type_info*__dst, const void*__obj,
-               __upcast_result& __restrict __result) const;
-  };
-
-  // Type information for a class with multiple and/or virtual bases.
-  class __vmi_class_type_info : public __class_type_info 
-  {
-  public:
-    unsigned int               __flags;  // Details about the class hierarchy.
-    unsigned int               __base_count;  // Number of direct bases.
-
-    // The array of bases uses the trailing array struct hack so this
-    // class is not constructable with a normal constructor. It is
-    // internally generated by the compiler.
-    __base_class_type_info     __base_info[1];  // Array of bases.
-
-    explicit 
-    __vmi_class_type_info(const char* __n, int ___flags)
-    : __class_type_info(__n), __flags(___flags), __base_count(0) { }
-
-    virtual 
-    ~__vmi_class_type_info();
-
-    // Implementation defined types.
-    enum __flags_masks 
-      {
-       __non_diamond_repeat_mask = 0x1, // Distinct instance of repeated base.
-       __diamond_shaped_mask = 0x2, // Diamond shaped multiple inheritance.
-       __flags_unknown_mask = 0x10
-      };
-
-  protected:
-    // Implementation defined member functions.
-    virtual bool 
-    __do_dyncast(ptrdiff_t __src2dst, __sub_kind __access_path,
-                const __class_type_info* __dst_type, const void* __obj_ptr,
-                const __class_type_info* __src_type, const void* __src_ptr,
-                __dyncast_result& __result) const;
-
-    virtual __sub_kind 
-    __do_find_public_src(ptrdiff_t __src2dst, const void* __obj_ptr, 
-                        const __class_type_info* __src_type,
-                        const void* __src_ptr) const;
-    
-    virtual bool 
-    __do_upcast(const __class_type_info* __dst, const void* __obj,
-               __upcast_result& __restrict __result) const;
-  };
-
-  // Dynamic cast runtime.
-  // src2dst has the following possible values
-  //  >-1: src_type is a unique public non-virtual base of dst_type
-  //       dst_ptr + src2dst == src_ptr
-  //   -1: unspecified relationship
-  //   -2: src_type is not a public base of dst_type
-  //   -3: src_type is a multiple public non-virtual base of dst_type
-  extern "C" void*
-  __dynamic_cast(const void* __src_ptr, // Starting object.
-                const __class_type_info* __src_type, // Static type of object.
-                const __class_type_info* __dst_type, // Desired target type.
-                ptrdiff_t __src2dst); // How src and dst are related.
-
-
-  // Returns the type_info for the currently handled exception [15.3/8], or
-  // null if there is none.
-  extern "C" std::type_info*
-  __cxa_current_exception_type();
-} // namespace __cxxabiv1
 
 // User programs should use the alias `abi'. 
 namespace abi = __cxxabiv1;
index 40bb839..0de8930 100644 (file)
 
 #include "typeinfo"
 #include "exception"
-#include "unwind-cxx.h"
+#include <cxxabi.h>
 
 std::exception::~exception() throw() { }
 
 std::bad_exception::~bad_exception() throw() { }
 
+abi::__forced_unwind::~__forced_unwind() throw() { }
+
+abi::__foreign_exception::~__foreign_exception() throw() { }
+
 const char* 
 std::exception::what() const throw()
 {
index 2bdb017..bbcc007 100644 (file)
@@ -30,6 +30,7 @@
 #include <bits/c++config.h>
 #include <cstdlib>
 #include <exception_defines.h>
+#include <cxxabi.h>
 #include "unwind-cxx.h"
 
 using namespace __cxxabiv1;
@@ -541,13 +542,19 @@ PERSONALITY_FUNCTION (int version,
       bool saw_cleanup = false;
       bool saw_handler = false;
 
-      // During forced unwinding, we only run cleanups.  With a foreign
-      // exception class, there's no exception type.
-      // ??? What to do about GNU Java and GNU Ada exceptions.
-
-      if ((actions & _UA_FORCE_UNWIND)
-         || foreign_exception)
-       throw_type = 0;
+      // During forced unwinding, match a magic exception type.
+      if (actions & _UA_FORCE_UNWIND)
+       {
+         throw_type = &typeid(abi::__forced_unwind);
+         thrown_ptr = 0;
+       }
+      // With a foreign exception class, there's no exception type.
+      // ??? What to do about GNU Java and GNU Ada exceptions?
+      else if (foreign_exception)
+       {
+         throw_type = &typeid(abi::__foreign_exception);
+         thrown_ptr = 0;
+       }
       else
 #ifdef __ARM_EABI_UNWINDER__
        throw_type = ue_header;
@@ -590,7 +597,9 @@ PERSONALITY_FUNCTION (int version,
              // object to stuff bits in for __cxa_call_unexpected to use.
              // Allow them iff the exception spec is non-empty.  I.e.
              // a throw() specification results in __unexpected.
-             if (throw_type
+             if ((throw_type
+                  && !(actions & _UA_FORCE_UNWIND)
+                  && !foreign_exception)
                  ? ! check_exception_spec (&info, throw_type, thrown_ptr,
                                            ar_filter)
                  : empty_exception_spec (&info, ar_filter))
index 83b20b9..b29040c 100644 (file)
@@ -114,6 +114,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -180,6 +185,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              if (traits_type::eq_int_type(__c, __eof))
                __err |= ios_base::eofbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
index 3fbee2c..fc140c0 100644 (file)
@@ -127,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
            __newsize = __ix + 1;
            try
              { __words = new _Words[__newsize]; }
-           catch (...)
+           catch(...)
              {
                _M_streambuf_state |= badbit;
                if (_M_streambuf_state & _M_exception)
@@ -172,7 +172,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       {
        try 
          { (*__p->_M_fn) (__e, *this, __p->_M_index); } 
-       catch (...) 
+       catch(...) 
          { }
        __p = __p->_M_next;
       }
index 5c7ab2e..62d42ee 100644 (file)
@@ -142,7 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
            wclog.flush();    
 #endif
          }
-       catch (...)
+       catch(...)
          { }
       }
   } 
index 0f24340..319202e 100644 (file)
@@ -91,6 +91,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
@@ -177,6 +182,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                  __sb->sbumpc();
                }
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -251,6 +261,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              *__s = __char_type();
              __in.width(0);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { __in._M_setstate(ios_base::badbit); }
        }
@@ -321,6 +336,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                __err |= ios_base::eofbit;
              __in.width(0);
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -401,6 +421,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -473,6 +498,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
        }
@@ -559,6 +589,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                  __sb->sbumpc();
                }
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             this->_M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            { this->_M_setstate(ios_base::badbit); }
          if (__err)
@@ -632,6 +667,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
              else
                __err |= ios_base::failbit;
            }
+         catch(__cxxabiv1::__forced_unwind&)
+           {
+             __in._M_setstate(ios_base::badbit);
+             __throw_exception_again;
+           }
          catch(...)
            {
              // _GLIBCXX_RESOLVE_LIB_DEFECTS