This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] PATCH to libstdc++ for forced unwind handling (c++/28145)


PR 28145 is a long-standing thorn in my foot having to do with the broken state of pthread_cancel with C++ under recent versions of glibc since it was implemented using the execption handling unwinder. Basically, due to intractable disagreements, the cancellation exception is catchable normally, but if it isn't rethrown the process aborts.

To make this even less useful, all I/O routines in the iostream library catch and discard all exceptions. And since most cancellation points are I/O routines, this means that a deferred cancellation will be thrown at exactly the point where it is most likely to be discarded, killing the program.

This patch works around the iostream part of the problem by allowing users to explicitly catch forced unwind, then explicitly rethrowing it wherever iostreams wants to discard exceptions.

This is not a complete fix for the cancellation breakage; it can still cause the program to die if other code discards the exception, or if it trips another terminate() condition. But it's a step forward.

I had to split out the guts of cxxabi.h to cxxabi-internal.h so that I could include it in standard library headers without introducing the name 'abi' which is in the user's symbol space.

Most of the rethrow changes are pretty mechanical. The only non-trivial ones are basic_filebuf::close and operator<< (basic_ostream, const char*), where I needed to change some clean up actions to be done via destructor rather than explicitly in the function. The former in particular would be much simpler with 'finally' in the language.

Tested x86_64-pc-linux-gnu. Any comments before I check it in?
2007-05-03  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/basic_string.tcc (operator>>, getline): Likewise.
	* include/bits/fstream.tcc (basic_filebuf::close): Likewise.
	* include/ext/vstring.cc (operator>>, getline): 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.

Index: libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp
===================================================================
*** libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp	(revision 124094)
--- libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp	(working copy)
*************** set_loads(std::pair<float, float> load_p
*** 265,271 ****
        m_load_max = load_pair.second;
        do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2)));
      }
!   catch (...)
      {
        m_load_min = old_load_min;
        m_load_max = old_load_max;
--- 265,271 ----
        m_load_max = load_pair.second;
        do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2)));
      }
!   catch(...)
      {
        m_load_min = old_load_min;
        m_load_max = old_load_max;
Index: libstdc++-v3/include/ext/vstring.tcc
===================================================================
*** libstdc++-v3/include/ext/vstring.tcc	(revision 124094)
--- libstdc++-v3/include/ext/vstring.tcc	(working copy)
***************
*** 38,43 ****
--- 38,45 ----
  
  #pragma GCC system_header
  
+ #include <cxxabi-internal.h>
+ 
  _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
  
    template<typename _CharT, typename _Traits, typename _Alloc,
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 598,603 ****
--- 600,610 ----
  		__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
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 669,674 ****
--- 676,686 ----
  	      else
  		__err |= __ios_base::failbit;
  	    }
+ 	  catch(__cxxabiv1::__forced_unwind&)
+ 	    {
+ 	      __in._M_setstate(ios_base::badbit);
+ 	      __throw_exception_again;
+ 	    }
  	  catch(...)
  	    {
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
Index: libstdc++-v3/include/bits/locale_classes.h
===================================================================
*** libstdc++-v3/include/bits/locale_classes.h	(revision 124094)
--- libstdc++-v3/include/bits/locale_classes.h	(working copy)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 408,414 ****
  	{
  	  try
  	    { delete this; }
! 	  catch (...)
  	    { }
  	}
      }
--- 408,414 ----
  	{
  	  try
  	    { delete this; }
! 	  catch(...)
  	    { }
  	}
      }
Index: libstdc++-v3/include/bits/istream.tcc
===================================================================
*** libstdc++-v3/include/bits/istream.tcc	(revision 124094)
--- libstdc++-v3/include/bits/istream.tcc	(working copy)
***************
*** 43,48 ****
--- 43,50 ----
  
  #pragma GCC system_header
  
+ #include <cxxabi-internal.h>
+ 
  _GLIBCXX_BEGIN_NAMESPACE(std)
  
    template<typename _CharT, typename _Traits>
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 98,103 ****
--- 100,110 ----
  		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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 163,168 ****
--- 170,180 ----
  	      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); }
  	}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 194,199 ****
--- 206,216 ----
  	      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); }
  	}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 226,231 ****
--- 243,253 ----
  	      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); }
  	}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 264,269 ****
--- 286,296 ----
  	      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); }
  	}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 307,312 ****
--- 334,344 ----
  	      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); }
  	}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 355,360 ****
--- 387,397 ----
                      __err |= ios_base::failbit;
                  }
              }
+ 	  catch(__cxxabiv1::__forced_unwind&)
+ 	    {
+ 	      this->_M_setstate(ios_base::badbit);
+ 	      __throw_exception_again;
+ 	    }
            catch(...)
              { this->_M_setstate(ios_base::badbit); }
          }
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 392,397 ****
--- 429,439 ----
  	      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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 449,454 ****
--- 491,501 ----
  	      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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 509,514 ****
--- 556,566 ----
  		  __sb->sbumpc();
  		}
              }
+ 	  catch(__cxxabiv1::__forced_unwind&)
+ 	    {
+ 	      this->_M_setstate(ios_base::badbit);
+ 	      __throw_exception_again;
+ 	    }
            catch(...)
              { this->_M_setstate(ios_base::badbit); }
            if (__err)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 534,539 ****
--- 586,596 ----
  	      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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 558,563 ****
--- 615,625 ----
  	      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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 585,590 ****
--- 647,657 ----
  	      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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 613,618 ****
--- 680,690 ----
  		  || 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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 641,646 ****
--- 713,723 ----
  		  || 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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 672,677 ****
--- 749,759 ----
  		    __ret = 0;
  		}
  	    }
+ 	  catch(__cxxabiv1::__forced_unwind&)
+ 	    {
+ 	      this->_M_setstate(ios_base::badbit);
+ 	      __throw_exception_again;
+ 	    }
  	  catch(...)
  	    { this->_M_setstate(ios_base::badbit); }
  	  if (__err)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 694,699 ****
--- 776,786 ----
  	    __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;
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 720,725 ****
--- 807,817 ----
  		__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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 748,753 ****
--- 840,850 ----
  		__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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 775,780 ****
--- 872,882 ----
  	      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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 828,833 ****
--- 930,940 ----
  	      *__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: libstdc++-v3/include/bits/ostream.tcc
===================================================================
*** libstdc++-v3/include/bits/ostream.tcc	(revision 124094)
--- libstdc++-v3/include/bits/ostream.tcc	(working copy)
***************
*** 43,48 ****
--- 43,51 ----
  
  #pragma GCC system_header
  
+ #include <memory>
+ #include <cxxabi-internal.h>
+ 
  _GLIBCXX_BEGIN_NAMESPACE(std)
  
    template<typename _CharT, typename _Traits>
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 76,81 ****
--- 79,89 ----
  		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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 126,131 ****
--- 134,144 ----
  	      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); }
  	}
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 157,163 ****
  	      if (traits_type::eq_int_type(__put, traits_type::eof()))
  		__err |= ios_base::badbit;
  	    }
! 	  catch (...)
  	    { this->_M_setstate(ios_base::badbit); }
  	  if (__err)
  	    this->setstate(__err);
--- 170,181 ----
  	      if (traits_type::eq_int_type(__put, traits_type::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)
  	    this->setstate(__err);
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 182,188 ****
  	{
  	  try
  	    { _M_write(__s, __n); }
! 	  catch (...)
  	    { this->_M_setstate(ios_base::badbit); }
  	}
        return *this;
--- 200,211 ----
  	{
  	  try
  	    { _M_write(__s, __n); }
! 	  catch(__cxxabiv1::__forced_unwind&)
! 	    {
! 	      this->_M_setstate(ios_base::badbit);		
! 	      __throw_exception_again;
! 	    }
! 	  catch(...)
  	    { this->_M_setstate(ios_base::badbit); }
  	}
        return *this;
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 202,207 ****
--- 225,235 ----
  	  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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 220,225 ****
--- 248,258 ----
  	  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;
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 245,250 ****
--- 278,288 ----
  		__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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 272,277 ****
--- 310,320 ----
  		__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)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 289,319 ****
  	{
  	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  	  // 167.  Improper use of traits_type::length()
! 	  const size_t __clen = char_traits<char>::length(__s);      
! 	  _CharT* __ws = 0;
  	  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;
- 	    }
- 
- 	  try
- 	    {
  	      __ostream_insert(__out, __ws, __clen);
- 	      delete [] __ws;
  	    }
! 	  catch(...)
  	    {
! 	      delete [] __ws;
  	      __throw_exception_again;
  	    }
  	}
        return __out;
      }
--- 332,353 ----
  	{
  	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  	  // 167.  Improper use of traits_type::length()
! 	  const size_t __clen = char_traits<char>::length(__s);
  	  try
  	    { 
! 	      auto_ptr<_CharT> __sp (new _CharT[__clen]);
! 	      _CharT *__ws = __sp.get();
  	      for (size_t  __i = 0; __i < __clen; ++__i)
  		__ws[__i] = __out.widen(__s[__i]);
  	      __ostream_insert(__out, __ws, __clen);
  	    }
! 	  catch(__cxxabiv1::__forced_unwind&)
  	    {
! 	      __out._M_setstate(ios_base::badbit);
  	      __throw_exception_again;
  	    }
+ 	  catch(...)
+ 	    { __out._M_setstate(ios_base::badbit); }
  	}
        return __out;
      }
Index: libstdc++-v3/include/bits/basic_string.tcc
===================================================================
*** libstdc++-v3/include/bits/basic_string.tcc	(revision 124094)
--- libstdc++-v3/include/bits/basic_string.tcc	(working copy)
***************
*** 46,51 ****
--- 46,53 ----
  
  #pragma GCC system_header
  
+ #include <cxxabi-internal.h>
+ 
  _GLIBCXX_BEGIN_NAMESPACE(std)
  
    template<typename _CharT, typename _Traits, typename _Alloc>
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 1015,1020 ****
--- 1017,1027 ----
  		__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
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 1074,1079 ****
--- 1081,1091 ----
  	      else
  		__err |= __ios_base::failbit;
  	    }
+ 	  catch(__cxxabiv1::__forced_unwind&)
+ 	    {
+ 	      __in._M_setstate(__ios_base::badbit);
+ 	      __throw_exception_again;
+ 	    }
  	  catch(...)
  	    {
  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
Index: libstdc++-v3/include/bits/fstream.tcc
===================================================================
*** libstdc++-v3/include/bits/fstream.tcc	(revision 124094)
--- libstdc++-v3/include/bits/fstream.tcc	(working copy)
***************
*** 42,47 ****
--- 42,49 ----
  
  #pragma GCC system_header
  
+ #include <cxxabi-internal.h>
+ 
  _GLIBCXX_BEGIN_NAMESPACE(std)
  
    template<typename _CharT, typename _Traits>
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 127,162 ****
    template<typename _CharT, typename _Traits>
      typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
      basic_filebuf<_CharT, _Traits>::
!     close() throw()
      {
!       __filebuf_type* __ret = NULL;
!       if (this->is_open())
! 	{
! 	  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;
      }
  
    template<typename _CharT, typename _Traits>
--- 129,179 ----
    template<typename _CharT, typename _Traits>
      typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
      basic_filebuf<_CharT, _Traits>::
!     close()
      {
!       if (!this->is_open())
! 	return NULL;
! 
!       bool __testfail = false;
!       {
! 	// NB: Do this here so that re-opened filebufs will be cool...
! 	struct __close_sentry
! 	{
! 	  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: libstdc++-v3/include/debug/deque
===================================================================
*** libstdc++-v3/include/debug/deque	(revision 124094)
--- libstdc++-v3/include/debug/deque	(working copy)
*************** namespace __debug
*** 313,319 ****
  		return iterator(_Base::erase(__first.base(), __last.base()),
  				this);
  	      }
! 	    catch (...)
  	      {
  		this->_M_revalidate_singular();
  		__throw_exception_again;
--- 313,319 ----
  		return iterator(_Base::erase(__first.base(), __last.base()),
  				this);
  	      }
! 	    catch(...)
  	      {
  		this->_M_revalidate_singular();
  		__throw_exception_again;
Index: libstdc++-v3/include/tr1/hypergeometric.tcc
===================================================================
*** libstdc++-v3/include/tr1/hypergeometric.tcc	(revision 124094)
--- libstdc++-v3/include/tr1/hypergeometric.tcc	(working copy)
*************** _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
*** 613,619 ****
                __sgn_g1cb = __log_gamma_sign(__c - __b);
                __ln_g1cb = __log_gamma(__c - __b);
              }
!           catch (...)
              {
                __ok1 = false;
              }
--- 613,619 ----
                __sgn_g1cb = __log_gamma_sign(__c - __b);
                __ln_g1cb = __log_gamma(__c - __b);
              }
!           catch(...)
              {
                __ok1 = false;
              }
*************** _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
*** 628,634 ****
                __sgn_g2b = __log_gamma_sign(__b);
                __ln_g2b = __log_gamma(__b);
              }
!           catch (...)
              {
                __ok2 = false;
              }
--- 628,634 ----
                __sgn_g2b = __log_gamma_sign(__b);
                __ln_g2b = __log_gamma(__b);
              }
!           catch(...)
              {
                __ok2 = false;
              }
Index: libstdc++-v3/include/std/bitset
===================================================================
*** libstdc++-v3/include/std/bitset	(revision 124094)
--- libstdc++-v3/include/std/bitset	(working copy)
***************
*** 56,61 ****
--- 56,62 ----
  #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) \
*************** _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL
*** 1271,1276 ****
--- 1272,1282 ----
  		    }
  		}
  	    }
+ 	  catch(__cxxabiv1::__forced_unwind&)
+ 	    {
+ 	      __is._M_setstate(__ios_base::badbit);		
+ 	      __throw_exception_again;
+ 	    }
  	  catch(...)
  	    { __is._M_setstate(__ios_base::badbit); }
  	}
Index: libstdc++-v3/include/std/fstream
===================================================================
*** libstdc++-v3/include/std/fstream	(revision 124094)
--- libstdc++-v3/include/std/fstream	(working copy)
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 274,280 ****
         *  If any operations fail, this function also fails.
        */
        __filebuf_type*
!       close() throw();
  
      protected:
        void
--- 274,280 ----
         *  If any operations fail, this function also fails.
        */
        __filebuf_type*
!       close();
  
      protected:
        void
Index: libstdc++-v3/libsupc++/cxxabi-internal.h
===================================================================
*** libstdc++-v3/libsupc++/cxxabi-internal.h	(revision 124094)
--- libstdc++-v3/libsupc++/cxxabi-internal.h	(working copy)
***************
*** 43,50 ****
   *  The header provides an interface to the C++ ABI.
   */
  
! #ifndef _CXXABI_H
! #define _CXXABI_H 1
  
  #pragma GCC visibility push(default)
  
--- 43,50 ----
   *  The header provides an interface to the C++ ABI.
   */
  
! #ifndef _CXXABI_INTERNAL_H
! #define _CXXABI_INTERNAL_H 1
  
  #pragma GCC visibility push(default)
  
*************** namespace __cxxabiv1
*** 525,537 ****
    // 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;
  
  #endif // __cplusplus
  
  #pragma GCC visibility pop
  
! #endif // __CXXABI_H 
--- 525,551 ----
    // 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: libstdc++-v3/libsupc++/eh_exception.cc
===================================================================
*** libstdc++-v3/libsupc++/eh_exception.cc	(revision 124094)
--- libstdc++-v3/libsupc++/eh_exception.cc	(working copy)
***************
*** 31,42 ****
  
  #include "typeinfo"
  #include "exception"
! #include "unwind-cxx.h"
  
  std::exception::~exception() throw() { }
  
  std::bad_exception::~bad_exception() throw() { }
  
  const char* 
  std::exception::what() const throw()
  {
--- 31,46 ----
  
  #include "typeinfo"
  #include "exception"
! #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: libstdc++-v3/libsupc++/cxxabi.h
===================================================================
*** libstdc++-v3/libsupc++/cxxabi.h	(revision 124094)
--- libstdc++-v3/libsupc++/cxxabi.h	(working copy)
***************
*** 48,531 ****
  
  #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*);
- 
-   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;
--- 48,56 ----
  
  #pragma GCC visibility push(default)
  
! #include <cxxabi-internal.h>
  
  #ifdef __cplusplus
  
  // User programs should use the alias `abi'. 
  namespace abi = __cxxabiv1;
Index: libstdc++-v3/libsupc++/eh_personality.cc
===================================================================
*** libstdc++-v3/libsupc++/eh_personality.cc	(revision 124094)
--- libstdc++-v3/libsupc++/eh_personality.cc	(working copy)
***************
*** 30,35 ****
--- 30,36 ----
  #include <bits/c++config.h>
  #include <cstdlib>
  #include <exception_defines.h>
+ #include <cxxabi.h>
  #include "unwind-cxx.h"
  
  using namespace __cxxabiv1;
*************** PERSONALITY_FUNCTION (int version,
*** 541,553 ****
        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;
        else
  #ifdef __ARM_EABI_UNWINDER__
  	throw_type = ue_header;
--- 542,560 ----
        bool saw_cleanup = false;
        bool saw_handler = false;
  
!       // 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;
*************** PERSONALITY_FUNCTION (int version,
*** 590,596 ****
  	      // 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
  		  ? ! check_exception_spec (&info, throw_type, thrown_ptr,
  					    ar_filter)
  		  : empty_exception_spec (&info, ar_filter))
--- 597,605 ----
  	      // 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
! 		   && !(actions & _UA_FORCE_UNWIND)
! 		   && !foreign_exception)
  		  ? ! check_exception_spec (&info, throw_type, thrown_ptr,
  					    ar_filter)
  		  : empty_exception_spec (&info, ar_filter))
Index: libstdc++-v3/config/abi/pre/gnu.ver
===================================================================
*** libstdc++-v3/config/abi/pre/gnu.ver	(revision 124094)
--- libstdc++-v3/config/abi/pre/gnu.ver	(working copy)
*************** CXXABI_1.3 {
*** 793,798 ****
--- 793,800 ----
      _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: libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
===================================================================
*** libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver	(revision 124094)
--- libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver	(working copy)
*************** CXXABI_1.7 {
*** 178,183 ****
--- 178,185 ----
      _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: gcc/testsuite/g++.dg/abi/forced.C
===================================================================
*** gcc/testsuite/g++.dg/abi/forced.C	(revision 0)
--- gcc/testsuite/g++.dg/abi/forced.C	(revision 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]