libstdc++/10132: filebuf destructor throws exceptions

Benjamin Kosnik bkoz@redhat.com
Fri Apr 25 00:56:00 GMT 2003


The following reply was made to PR libstdc++/10132; it has been noted by GNATS.

From: Benjamin Kosnik <bkoz@redhat.com>
To: =?ISO-8859-1?Q?P=E9tur_Run=F3lfsson?= <peturr02@ru.is>
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Subject: Re: libstdc++/10132: filebuf destructor throws exceptions
Date: Thu, 24 Apr 2003 19:48:40 -0500

 Like this.
 
 2003-04-24  Benjamin Kosnik  <bkoz@redhat.com>
 
 	PR libstdc++/10132
 	* include/std/std_fstream.h (basic_filebuf::is_open): Add throw()
 	exception specifications.
 	(basic_filebuf::close): Same.
 	(basic_filebuf::_M_pback_destroy): Same.
 	(basic_filebuf::_M_destroy_internal_buffer): Same.
 	(basic_filebuf): Remove __res_type typedef.=09
 	* src/fstream.cc: Same.
 	* include/bits/fstream.tcc
 	(basic_filebuf::_M_convert_to_external): Simplify.
 	(basic_filebuf::seekoff): Use has_facet	before use_facet.
 	(basic_filebuf::close): Add exception specification of throw().
 	* testsuite/27_io/basic_filebuf/cons: New.
 	* testsuite/27_io/basic_filebuf/cons/wchar_t: New.=09
 	* testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc: New.=09
 	* testsuite/27_io/basic_filebuf/seekoff/10132-2.cc: New.
 	* testsuite/27_io/basic_filebuf/seekpos/10132-3.cc: New.
 
 Index: include/bits/fstream.tcc
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/fstream.tcc,v
 retrieving revision 1.65
 diff -c -p -r1.65 fstream.tcc
 *** include/bits/fstream.tcc	22 Apr 2003 17:32:25 -0000	1.65
 --- include/bits/fstream.tcc	24 Apr 2003 23:57:52 -0000
 *************** namespace std
 *** 60,66 ****
     template<typename _CharT, typename _Traits>
       void
       basic_filebuf<_CharT, _Traits>::
 !     _M_destroy_internal_buffer()
       {
         if (_M_buf_allocated)
   	{
 --- 60,66 ----
     template<typename _CharT, typename _Traits>
       void
       basic_filebuf<_CharT, _Traits>::
 !     _M_destroy_internal_buffer() throw()
       {
         if (_M_buf_allocated)
   	{
 *************** namespace std
 *** 114,153 ****
     template<typename _CharT, typename _Traits>
       typename basic_filebuf<_CharT, _Traits>::__filebuf_type*=20
       basic_filebuf<_CharT, _Traits>::
 !     close()
       {
         __filebuf_type* __ret =3D NULL;
         if (this->is_open())
   	{
   	  bool __testfail =3D false;
 ! 	  const int_type __eof =3D traits_type::eof();
 ! 	  const bool __testput =3D this->_M_out_beg < this->_M_out_lim;
  =20
 ! 	  if (__testput=20
 ! 	      && traits_type::eq_int_type(_M_really_overflow(__eof), __eof))
 ! 	    __testfail =3D true;
  =20
   #if 0
 ! 	  // XXX not done
 ! 	  if (_M_last_overflowed)
   	    {
 ! 	      _M_output_unshift();
 ! 	      _M_really_overflow(__eof);
   	    }
 ! #endif
 !=20
   	  // NB: Do this here so that re-opened filebufs will be cool...
   	  this->_M_mode =3D ios_base::openmode(0);
   	  _M_destroy_internal_buffer();
   	  _M_pback_destroy();
 !=20
   	  if (!_M_file.close())
   	    __testfail =3D true;
  =20
   	  if (!__testfail)
   	    __ret =3D this;
   	}
 !       _M_last_overflowed =3D false;=09
         return __ret;
       }
  =20
 --- 114,161 ----
     template<typename _CharT, typename _Traits>
       typename basic_filebuf<_CharT, _Traits>::__filebuf_type*=20
       basic_filebuf<_CharT, _Traits>::
 !     close() throw()
       {
         __filebuf_type* __ret =3D NULL;
         if (this->is_open())
   	{
   	  bool __testfail =3D false;
 ! 	  try
 ! 	    {
 ! 	      const int_type __eof =3D traits_type::eof();
 ! 	      const bool __testput =3D this->_M_out_beg < this->_M_out_lim;
  =20
 ! 	      if (__testput=20
 ! 		  && traits_type::eq_int_type(_M_really_overflow(__eof),=20
 ! 					      __eof))
 ! 		__testfail =3D true;
  =20
   #if 0
 ! 	      // XXX not done
 ! 	      if (_M_last_overflowed)
 ! 		{
 ! 		  _M_output_unshift();
 ! 		  _M_really_overflow(__eof);
 ! 		}
 ! #endif
 ! 	    }
 ! 	  catch(...)
   	    {
 ! 	      __testfail =3D true;
   	    }
 ! 	     =20
   	  // NB: Do this here so that re-opened filebufs will be cool...
   	  this->_M_mode =3D ios_base::openmode(0);
   	  _M_destroy_internal_buffer();
   	  _M_pback_destroy();
 ! 	 =20
   	  if (!_M_file.close())
   	    __testfail =3D true;
  =20
   	  if (!__testfail)
   	    __ret =3D this;
   	}
 !       _M_last_overflowed =3D false;
         return __ret;
       }
  =20
 *************** namespace std
 *** 160,167 ****
         const bool __testin =3D this->_M_mode & ios_base::in;
         const locale __loc =3D this->getloc();
         const __codecvt_type& __cvt =3D use_facet<__codecvt_type>(__loc);
 !       // Sync with stdio.
 !       const bool __sync =3D this->_M_buf_size <=3D 1;
  =20
         if (__testin && this->is_open())
   	{
 --- 168,174 ----
         const bool __testin =3D this->_M_mode & ios_base::in;
         const locale __loc =3D this->getloc();
         const __codecvt_type& __cvt =3D use_facet<__codecvt_type>(__loc);
 !       const bool __testsync =3D this->_M_buf_size <=3D 1;
  =20
         if (__testin && this->is_open())
   	{
 *************** namespace std
 *** 170,176 ****
   	  // For a stateful encoding (-1) the pending sequence might be just
   	  // shift and unshift prefixes with no actual character.
   	  if (__cvt.encoding() >=3D 0)
 ! 	    __ret +=3D _M_file.showmanyc_helper(__sync) / __cvt.max_length();
   	}
  =20
         _M_last_overflowed =3D false;=09
 --- 177,183 ----
   	  // For a stateful encoding (-1) the pending sequence might be just
   	  // shift and unshift prefixes with no actual character.
   	  if (__cvt.encoding() >=3D 0)
 ! 	    __ret +=3D _M_file.showmanyc_helper(__testsync) / __cvt.max_length();
   	}
  =20
         _M_last_overflowed =3D false;=09
 *************** namespace std
 *** 283,297 ****
       _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
   			   streamsize& __elen, streamsize& __plen)
       {
         const locale __loc =3D this->getloc();
         const __codecvt_type& __cvt =3D use_facet<__codecvt_type>(__loc);
 -       // Sync with stdio.
 -       const bool __sync =3D this->_M_buf_size <=3D 1;
  =20
         if (__cvt.always_noconv() && __ilen)
   	{
 ! 	  __elen +=3D
 ! 	    _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen, __sync);
   	  __plen +=3D __ilen;
   	}
         else
 --- 290,303 ----
       _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
   			   streamsize& __elen, streamsize& __plen)
       {
 +       const bool __testsync =3D this->_M_buf_size <=3D 1;
         const locale __loc =3D this->getloc();
         const __codecvt_type& __cvt =3D use_facet<__codecvt_type>(__loc);
  =20
         if (__cvt.always_noconv() && __ilen)
   	{
 ! 	  __elen +=3D _M_file.xsputn(reinterpret_cast<char*>(__ibuf),=20
 ! 				   __ilen, __testsync);
   	  __plen +=3D __ilen;
   	}
         else
 *************** namespace std
 *** 304,330 ****
   	  char* __buf =3D static_cast<char*>(__builtin_alloca(__blen));
   	  char* __bend;
   	  const char_type* __iend;
 ! 	  __res_type __r =3D __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,=20
 ! 		 		     __iend, __buf, __buf + __blen, __bend);
 !=20
   	  if (__r =3D=3D codecvt_base::ok || __r =3D=3D codecvt_base::partial)
   	    __blen =3D __bend - __buf;
 - 	  // Similarly to the always_noconv case above.
   	  else if (__r =3D=3D codecvt_base::noconv)
   	    {
   	      __buf =3D reinterpret_cast<char*>(__ibuf);
   	      __blen =3D __ilen;
   	    }
 ! 	  // Result =3D=3D error
 ! 	  else=20
 ! 	    __blen =3D 0;
   	 =20
   	  if (__blen)
   	    {
 ! 	      __elen +=3D _M_file.xsputn(__buf, __blen, __sync);
   	      __plen +=3D __blen;
   	    }
 !=20
   	  // Try once more for partial conversions.
   	  if (__r =3D=3D codecvt_base::partial)
   	    {
 --- 310,339 ----
   	  char* __buf =3D static_cast<char*>(__builtin_alloca(__blen));
   	  char* __bend;
   	  const char_type* __iend;
 ! 	  codecvt_base::result __r;
 ! 	  __r =3D __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
 ! 			  __iend, __buf, __buf + __blen, __bend);
 ! 	 =20
   	  if (__r =3D=3D codecvt_base::ok || __r =3D=3D codecvt_base::partial)
   	    __blen =3D __bend - __buf;
   	  else if (__r =3D=3D codecvt_base::noconv)
   	    {
 + 	      // Same as the always_noconv case above.
   	      __buf =3D reinterpret_cast<char*>(__ibuf);
   	      __blen =3D __ilen;
   	    }
 ! 	  else
 ! 	    {
 ! 	      // Result =3D=3D error=20
 ! 	      __blen =3D 0;
 ! 	    }
   	 =20
   	  if (__blen)
   	    {
 ! 	      __elen +=3D _M_file.xsputn(__buf, __blen, __testsync);
   	      __plen +=3D __blen;
   	    }
 ! 	 =20
   	  // Try once more for partial conversions.
   	  if (__r =3D=3D codecvt_base::partial)
   	    {
 *************** namespace std
 *** 333,349 ****
   	      __r =3D __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,=20
   			      __iend, __buf, __buf + __blen, __bend);
   	      if (__r !=3D codecvt_base::error)
 - 		__rlen =3D __bend - __buf;
 - 	      else
 - 		{
 - 		  __rlen =3D 0;
 - 		  // Signal to the caller (_M_really_overflow) that
 - 		  // codecvt::out eventually failed.
 - 		  __elen =3D 0;		 =20
 - 		}
 - 	      if (__rlen)
   		{
 ! 		  __elen +=3D _M_file.xsputn(__buf, __rlen, __sync);
   		  __plen +=3D __rlen;
   		}
   	    }
 --- 342,350 ----
   	      __r =3D __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,=20
   			      __iend, __buf, __buf + __blen, __bend);
   	      if (__r !=3D codecvt_base::error)
   		{
 ! 		  __rlen =3D __bend - __buf;
 ! 		  __elen +=3D _M_file.xsputn(__buf, __rlen, __testsync);
   		  __plen +=3D __rlen;
   		}
   	    }
 *************** namespace std
 *** 358,365 ****
         int_type __ret =3D traits_type::eof();
         const bool __testput =3D this->_M_out_beg < this->_M_out_lim;
         const bool __testunbuffered =3D _M_file.is_open() && !this->_M_buf_=
 size;
 !       // Sync with stdio.
 !       const bool __sync =3D this->_M_buf_size <=3D 1;
  =20
         if (__testput || __testunbuffered)
   	{
 --- 359,365 ----
         int_type __ret =3D traits_type::eof();
         const bool __testput =3D this->_M_out_beg < this->_M_out_lim;
         const bool __testunbuffered =3D _M_file.is_open() && !this->_M_buf_=
 size;
 !       const bool __testsync =3D this->_M_buf_size <=3D 1;
  =20
         if (__testput || __testunbuffered)
   	{
 *************** namespace std
 *** 373,379 ****
   	  if (_M_filepos && _M_filepos !=3D this->_M_out_beg)
   	    {
   	      off_type __off =3D this->_M_out_beg - _M_filepos;
 ! 	      _M_file.seekoff(__off, ios_base::cur, __sync);
   	    }
  =20
   	  // Convert internal buffer to external representation, output.
 --- 373,379 ----
   	  if (_M_filepos && _M_filepos !=3D this->_M_out_beg)
   	    {
   	      off_type __off =3D this->_M_out_beg - _M_filepos;
 ! 	      _M_file.seekoff(__off, ios_base::cur, __testsync);
   	    }
  =20
   	  // Convert internal buffer to external representation, output.
 *************** namespace std
 *** 394,400 ****
   		  char_type __pending =3D traits_type::to_char_type(__c);
   		  _M_convert_to_external(&__pending, 1, __elen, __plen);
  =20
 ! 		  // User code must flush when switching modes (thus don't sync).
   		  if (__elen =3D=3D __plen && __elen)
   		    {
   		      _M_set_indeterminate();
 --- 394,401 ----
   		  char_type __pending =3D traits_type::to_char_type(__c);
   		  _M_convert_to_external(&__pending, 1, __elen, __plen);
  =20
 ! 		  // User code must flush when switching modes (thus
 ! 		  // don't sync).
   		  if (__elen =3D=3D __plen && __elen)
   		    {
   		      _M_set_indeterminate();
 *************** namespace std
 *** 446,460 ****
         pos_type __ret =3D  pos_type(off_type(-1));=20
         const bool __testin =3D (ios_base::in & this->_M_mode & __mode) !=
 =3D 0;
         const bool __testout =3D (ios_base::out & this->_M_mode & __mode) !=
 =3D 0;
 !       // Sync with stdio.
 !       const bool __sync =3D this->_M_buf_size <=3D 1;
        =20
 !       // Should probably do has_facet checks here.
 !       int __width =3D use_facet<__codecvt_type>(this->_M_buf_locale).enco=
 ding();
         if (__width < 0)
   	__width =3D 0;
 !       const bool __testfail =3D __off !=3D 0 && __width <=3D 0;
 !      =20
         if (this->is_open() && !__testfail && (__testin || __testout))=20
   	{
   	  // Ditch any pback buffers to avoid confusion.
 --- 447,461 ----
         pos_type __ret =3D  pos_type(off_type(-1));=20
         const bool __testin =3D (ios_base::in & this->_M_mode & __mode) !=
 =3D 0;
         const bool __testout =3D (ios_base::out & this->_M_mode & __mode) !=
 =3D 0;
 !       const bool __testsync =3D this->_M_buf_size <=3D 1;
        =20
 !       int __width =3D 0;
 !       if (has_facet<__codecvt_type>(this->_M_buf_locale))
 ! 	  __width =3D use_facet<__codecvt_type>(this->_M_buf_locale).encoding();
         if (__width < 0)
   	__width =3D 0;
 !=20
 !       const bool __testfail =3D __off !=3D 0 && __width <=3D 0;     =20
         if (this->is_open() && !__testfail && (__testin || __testout))=20
   	{
   	  // Ditch any pback buffers to avoid confusion.
 *************** namespace std
 *** 480,501 ****
   		__computed_off +=3D this->_M_in_cur - _M_filepos;
  =20
   	      // Return pos_type(off_type(-1)) in case of failure.
 ! 	      __ret =3D _M_file.seekoff(__computed_off, __way, __sync, __mode);
   	      _M_set_indeterminate();
   	    }
   	  // NB: Need to do this in case _M_file in indeterminate
   	  // state, ie _M_file._offset =3D=3D -1
   	  else
   	    {
 ! 	      pos_type __tmp =3D
 ! 		_M_file.seekoff(__off, ios_base::cur,
 ! 				__sync, __mode);
   	      if (__tmp >=3D 0)
   		{
   		  // Seek successful.
   		  __ret =3D __tmp;
 ! 		  __ret +=3D
 ! 		    std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
   		}
   	    }
   	}
 --- 481,502 ----
   		__computed_off +=3D this->_M_in_cur - _M_filepos;
  =20
   	      // Return pos_type(off_type(-1)) in case of failure.
 ! 	      __ret =3D _M_file.seekoff(__computed_off, __way, __testsync,=20
 ! 				      __mode);
   	      _M_set_indeterminate();
   	    }
   	  // NB: Need to do this in case _M_file in indeterminate
   	  // state, ie _M_file._offset =3D=3D -1
   	  else
   	    {
 ! 	      pos_type __tmp =3D _M_file.seekoff(__off, ios_base::cur,=20
 ! 					       __testsync, __mode);
   	      if (__tmp >=3D 0)
   		{
   		  // Seek successful.
   		  __ret =3D __tmp;
 ! 		  __ret +=3D std::max(this->_M_out_cur, this->_M_in_cur)=20
 ! 		           - _M_filepos;
   		}
   	    }
   	}
 Index: include/std/std_fstream.h
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_fstream.h,v
 retrieving revision 1.29
 diff -c -p -r1.29 std_fstream.h
 *** include/std/std_fstream.h	22 Apr 2003 17:32:25 -0000	1.29
 --- include/std/std_fstream.h	24 Apr 2003 23:57:53 -0000
 *************** namespace std
 *** 81,87 ****
         typedef __basic_file<char>		        __file_type;
         typedef typename traits_type::state_type          __state_type;
         typedef codecvt<char_type, char, __state_type>    __codecvt_type;
 -       typedef typename __codecvt_type::result 	        __res_type;
         typedef ctype<char_type>                          __ctype_type;
         //@}
  =20
 --- 81,86 ----
 *************** namespace std
 *** 171,177 ****
         // Assumptions:
         // The pback buffer has only moved forward.
         void
 !       _M_pback_destroy()
         {
   	if (_M_pback_init)
   	  {
 --- 170,176 ----
         // Assumptions:
         // The pback buffer has only moved forward.
         void
 !       _M_pback_destroy() throw()
         {
   	if (_M_pback_init)
   	  {
 *************** namespace std
 *** 218,224 ****
          *  @brief  Returns true if the external file is open.
         */
         bool
 !       is_open() const { return _M_file.is_open(); }
  =20
         /**
          *  @brief  Opens an external file.
 --- 217,223 ----
          *  @brief  Returns true if the external file is open.
         */
         bool
 !       is_open() const throw() { return _M_file.is_open(); }
  =20
         /**
          *  @brief  Opens an external file.
 *************** namespace std
 *** 248,254 ****
          *  If any operations fail, this function also fails.
         */
         __filebuf_type*
 !       close();
  =20
       protected:
         /**
 --- 247,253 ----
          *  If any operations fail, this function also fails.
         */
         __filebuf_type*
 !       close() throw();
  =20
       protected:
         /**
 *************** namespace std
 *** 265,271 ****
          *  @endif
         */
         void
 !       _M_destroy_internal_buffer();
  =20
         // [27.8.1.4] overridden virtual functions
         // [documentation is inherited]
 --- 264,270 ----
          *  @endif
         */
         void
 !       _M_destroy_internal_buffer() throw();
  =20
         // [27.8.1.4] overridden virtual functions
         // [documentation is inherited]
 Index: src/fstream.cc
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvs/gcc/gcc/libstdc++-v3/src/fstream.cc,v
 retrieving revision 1.8
 diff -c -p -r1.8 fstream.cc
 *** src/fstream.cc	20 Apr 2003 13:54:45 -0000	1.8
 --- src/fstream.cc	24 Apr 2003 23:57:53 -0000
 *************** namespace std=20
 *** 43,50 ****
         int_type __ret =3D traits_type::eof();
         const bool __testin =3D _M_mode & ios_base::in;
         const bool __testout =3D _M_mode & ios_base::out;
 !       // Sync with stdio.
 !       const bool __sync =3D _M_buf_size <=3D 1;
  =20
         if (__testin)
   	{
 --- 43,49 ----
         int_type __ret =3D traits_type::eof();
         const bool __testin =3D _M_mode & ios_base::in;
         const bool __testout =3D _M_mode & ios_base::out;
 !       const bool __testsync =3D _M_buf_size <=3D 1;
  =20
         if (__testin)
   	{
 *************** namespace std=20
 *** 72,78 ****
   		_M_really_overflow();
   	      else if (_M_in_cur !=3D _M_filepos)
   		_M_file.seekoff(_M_in_cur - _M_filepos,
 ! 				ios_base::cur, __sync, ios_base::in);
   	    }
  =20
   	  if (__testinit || __testget)
 --- 71,77 ----
   		_M_really_overflow();
   	      else if (_M_in_cur !=3D _M_filepos)
   		_M_file.seekoff(_M_in_cur - _M_filepos,
 ! 				ios_base::cur, __testsync, ios_base::in);
   	    }
  =20
   	  if (__testinit || __testget)
 *************** namespace std=20
 *** 81,87 ****
   	      streamsize __ilen =3D 0;
  =20
   	      __elen =3D _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),=20
 ! 				      _M_buf_size, __sync);
   	      __ilen =3D __elen;
  =20
   	      if (0 < __ilen)
 --- 80,86 ----
   	      streamsize __ilen =3D 0;
  =20
   	      __elen =3D _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),=20
 ! 				      _M_buf_size, __testsync);
   	      __ilen =3D __elen;
  =20
   	      if (0 < __ilen)
 *************** namespace std=20
 *** 92,98 ****
   		  __ret =3D traits_type::to_int_type(*_M_in_cur);
   		  if (__bump)
   		    _M_in_cur_move(1);
 ! 		  else if (__sync)
   		    {
   		      // If we are synced with stdio, we have to unget the
   		      // character we just read so that the file pointer
 --- 91,97 ----
   		  __ret =3D traits_type::to_int_type(*_M_in_cur);
   		  if (__bump)
   		    _M_in_cur_move(1);
 ! 		  else if (__testsync)
   		    {
   		      // If we are synced with stdio, we have to unget the
   		      // character we just read so that the file pointer
 *************** namespace std=20
 *** 125,132 ****
         int_type __ret =3D traits_type::eof();
         const bool __testin =3D _M_mode & ios_base::in;
         const bool __testout =3D _M_mode & ios_base::out;
 !       // Sync with stdio.
 !       const bool __sync =3D _M_buf_size <=3D 1;
  =20
         if (__testin)
   	{
 --- 124,130 ----
         int_type __ret =3D traits_type::eof();
         const bool __testin =3D _M_mode & ios_base::in;
         const bool __testout =3D _M_mode & ios_base::out;
 !       const bool __testsync =3D _M_buf_size <=3D 1;
  =20
         if (__testin)
   	{
 *************** namespace std=20
 *** 154,192 ****
   		_M_really_overflow();
   	      else if (_M_in_cur !=3D _M_filepos)
   		_M_file.seekoff(_M_in_cur - _M_filepos,
 ! 				  ios_base::cur, __sync, ios_base::in);
   	    }
  =20
   	  if (__testinit || __testget)
   	    {
 - 	      const locale __loc =3D this->getloc();
 - 	      const __codecvt_type& __cvt =3D use_facet<__codecvt_type>(__loc);=
 =20
 -=20
   	      streamsize __elen =3D 0;
   	      streamsize __ilen =3D 0;
   	      if (__cvt.always_noconv())
   		{
   		  __elen =3D _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),=20
 ! 					  _M_buf_size, __sync);
   		  __ilen =3D __elen;
   		}
   	      else
   		{
   		  char* __buf =3D static_cast<char*>(__builtin_alloca(_M_buf_size));
 ! 		  __elen =3D _M_file.xsgetn(__buf, _M_buf_size, __sync);
 !=20
   		  const char* __eend;
   		  char_type* __iend;
 ! 		  __res_type __r =3D __cvt.in(_M_state_cur, __buf,=20
 ! 					    __buf + __elen, __eend, _M_in_beg,=20
 ! 					    _M_in_beg + _M_buf_size, __iend);
   		  if (__r =3D=3D codecvt_base::ok)
   		    __ilen =3D __iend - _M_in_beg;
   		  else=20
   		    {
   		      // Unwind.
   		      __ilen =3D 0;
 ! 		      _M_file.seekoff(-__elen, ios_base::cur, __sync, ios_base::in);
   		    }
   		}
  =20
 --- 152,190 ----
   		_M_really_overflow();
   	      else if (_M_in_cur !=3D _M_filepos)
   		_M_file.seekoff(_M_in_cur - _M_filepos,
 ! 				ios_base::cur, __testsync, ios_base::in);
   	    }
  =20
   	  if (__testinit || __testget)
   	    {
   	      streamsize __elen =3D 0;
   	      streamsize __ilen =3D 0;
 + 	      const locale __loc =3D this->getloc();
 + 	      const __codecvt_type& __cvt =3D use_facet<__codecvt_type>(__loc);
   	      if (__cvt.always_noconv())
   		{
   		  __elen =3D _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),=20
 ! 					  _M_buf_size, __testsync);
   		  __ilen =3D __elen;
   		}
   	      else
   		{
   		  char* __buf =3D static_cast<char*>(__builtin_alloca(_M_buf_size));
 ! 		  __elen =3D _M_file.xsgetn(__buf, _M_buf_size, __testsync);
 ! 		 =20
   		  const char* __eend;
   		  char_type* __iend;
 ! 		  codecvt_base::result __r;
 ! 		  __r =3D __cvt.in(_M_state_cur, __buf, __buf + __elen, __eend,=20
 ! 				 _M_in_beg, _M_in_beg + _M_buf_size, __iend);
   		  if (__r =3D=3D codecvt_base::ok)
   		    __ilen =3D __iend - _M_in_beg;
   		  else=20
   		    {
   		      // Unwind.
   		      __ilen =3D 0;
 ! 		      _M_file.seekoff(-__elen, ios_base::cur, __testsync,=20
 ! 				      ios_base::in);
   		    }
   		}
  =20
 *************** namespace std=20
 *** 198,204 ****
   		  __ret =3D traits_type::to_int_type(*_M_in_cur);
   		  if (__bump)
   		    _M_in_cur_move(1);
 ! 		  else if (__sync)
   		    {
   		      // If we are synced with stdio, we have to unget the
   		      // character we just read so that the file pointer
 --- 196,202 ----
   		  __ret =3D traits_type::to_int_type(*_M_in_cur);
   		  if (__bump)
   		    _M_in_cur_move(1);
 ! 		  else if (__testsync)
   		    {
   		      // If we are synced with stdio, we have to unget the
   		      // character we just read so that the file pointer
 Index: testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc
 diff -N testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc
 *** /dev/null	1 Jan 1970 00:00:00 -0000
 --- testsuite/27_io/basic_filebuf/cons/wchar_t/10132-1.cc	24 Apr 2003 23:57=
 :56 -0000
 ***************
 *** 0 ****
 --- 1,54 ----
 + // 2003-04-24 P=E9tur Run=F3lfsson <peturr02@ru.is>
 + // Copyright (C) 2003 Free Software Foundation, Inc.
 + //
 + // This file is part of the GNU ISO C++ Library.  This library is free
 + // software; you can redistribute it and/or modify it under the
 + // terms of the GNU General Public License as published by the
 + // Free Software Foundation; either version 2, or (at your option)
 + // any later version.
 +=20
 + // This library 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.
 +=20
 + // You should have received a copy of the GNU General Public License along
 + // with this library; see the file COPYING.  If not, write to the Free
 + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-130=
 7,
 + // USA.
 +=20
 + #include <fstream>
 + #include <locale>
 + #include <stdexcept>
 + #include <testsuite_hooks.h>
 +=20
 + class Cvt : public std::codecvt<wchar_t, char, std::mbstate_t>
 + {
 + protected:
 +   virtual std::codecvt_base::result
 +   do_out(std::mbstate_t&, const wchar_t*, const wchar_t*, const wchar_t*&=
 ,=20
 + 	 char*, char*, char*&) const
 +   { throw std::runtime_error("codecvt failed"); }
 + };
 +=20
 + int main()
 + {
 +   using namespace std;
 +   bool test =3D true;
 +=20
 +   locale loc =3D locale(locale::classic(), new Cvt);
 +   wfilebuf* fb =3D new wfilebuf;
 +   fb->pubimbue(loc);
 +   fb->open("tmp_10132", ios_base::out);
 +   fb->sputc(L'a');
 +  =20
 +   try
 +     {
 +       delete fb;
 +     }
 +   catch(exception& obj)
 +     {
 +       VERIFY( false );=20
 +     }
 +   return 0;
 + }
 Index: testsuite/27_io/basic_filebuf/seekoff/10132-2.cc
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: testsuite/27_io/basic_filebuf/seekoff/10132-2.cc
 diff -N testsuite/27_io/basic_filebuf/seekoff/10132-2.cc
 *** /dev/null	1 Jan 1970 00:00:00 -0000
 --- testsuite/27_io/basic_filebuf/seekoff/10132-2.cc	24 Apr 2003 23:57:56 -=
 0000
 ***************
 *** 0 ****
 --- 1,147 ----
 + // 2003-04-24 bkoz
 +=20
 + // Copyright (C) 2003 Free Software Foundation, Inc.
 + //
 + // This file is part of the GNU ISO C++ Library.  This library is free
 + // software; you can redistribute it and/or modify it under the
 + // terms of the GNU General Public License as published by the
 + // Free Software Foundation; either version 2, or (at your option)
 + // any later version.
 +=20
 + // This library 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.
 +=20
 + // You should have received a copy of the GNU General Public License along
 + // with this library; see the file COPYING.  If not, write to the Free
 + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-130=
 7,
 + // USA.
 +=20
 + // 27.8.1.1 - Template class basic_filebuf=20
 + // NB: This file is for testing basic_filebuf with NO OTHER INCLUDES.
 +=20
 + #include <fstream>
 + #include <testsuite_hooks.h>
 +=20
 + // libstdc++/10132, add on
 + class gnu_char_type
 + {
 +   unsigned long character;
 + public:
 +   // operator =3D=3D
 +   bool
 +   operator=3D=3D(const gnu_char_type& __lhs)=20
 +   { return character =3D=3D __lhs.character; }
 +=20
 +   // operator <
 +   bool
 +   operator<(const gnu_char_type& __lhs)=20
 +   { return character < __lhs.character; }
 +=20
 +   // default ctor
 +   gnu_char_type() { }
 +=20
 +   // to_char_type
 +   gnu_char_type(const unsigned long& __l) : character(__l) { }=20
 +=20
 +   // to_int_type
 +   operator unsigned long() const { return character; }
 + };
 +=20
 + // char_traits specialization
 + struct gnu_char_traits
 + {
 +   typedef gnu_char_type	char_type;
 +   typedef long  		int_type;
 +   typedef long 		pos_type;
 +   typedef unsigned long 	off_type;
 +   typedef long   		state_type;
 +  =20
 +   static void=20
 +   assign(char_type& __c1, const char_type& __c2) { }
 +  =20
 +   static bool=20
 +   eq(const char_type& __c1, const char_type& __c2) { return true; }
 +  =20
 +   static bool=20
 +   lt(const char_type& __c1, const char_type& __c2) { return true; }
 +  =20
 +   static int=20
 +   compare(const char_type* __s1, const char_type* __s2, size_t __n)
 +   { return 0; }
 +  =20
 +   static size_t
 +   length(const char_type* __s) { return 0; }
 +  =20
 +   static const char_type*=20
 +   find(const char_type* __s, size_t __n, const char_type& __a)
 +   { return __s; }
 +  =20
 +   static char_type*=20
 +   move(char_type* __s1, const char_type* __s2, size_t __n)
 +   { return __s1; }
 +  =20
 +   static char_type*=20
 +   copy(char_type* __s1, const char_type* __s2, size_t __n)
 +   { return __s1; }
 +  =20
 +   static char_type*=20
 +   assign(char_type* __s, size_t __n, char_type __a)
 +   { return __s; }
 +  =20
 +   static char_type=20
 +   to_char_type(const int_type& __c)
 +   { return char_type(); }
 +  =20
 +   static int_type=20
 +   to_int_type(const char_type& __c)
 +   { return int_type(); }
 +  =20
 +   static bool=20
 +   eq_int_type(const int_type& __c1, const int_type& __c2)
 +   { return true; }
 +  =20
 +   static int_type=20
 +   eof()
 +   { return int_type(); }
 +  =20
 +   static int_type=20
 +   not_eof(const int_type& __c)
 +   { return int_type(); }
 + };
 +=20
 + void test07()
 + {
 +   bool test =3D true;
 +   typedef std::basic_filebuf<gnu_char_type, gnu_char_traits> gnu_filebuf;
 +  =20
 +   try
 +     {=20
 +       // Need codecvt facet for width argument in seekoff.
 +       gnu_filebuf obj;
 +       obj.pubseekoff(2, std::ios_base::beg);
 +     }
 +   catch(std::exception& obj)
 +     {=20
 +       test =3D false;=20
 +       VERIFY( test );
 +     }
 + }
 +=20
 + #if !__GXX_WEAK__
 + // Explicitly instantiate for systems with no COMDAT or weak support.
 + template=20
 +   std::basic_filebuf<gnu_char_type>::int_type
 +   std::basic_filebuf<gnu_char_type>::_S_pback_size;
 + #endif
 +=20
 + int main()=20
 + {
 +   test07();
 +   return 0;
 + }
 +=20
 +=20
 +=20
 + // more surf!!!
 Index: testsuite/27_io/basic_filebuf/seekpos/10132-3.cc
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: testsuite/27_io/basic_filebuf/seekpos/10132-3.cc
 diff -N testsuite/27_io/basic_filebuf/seekpos/10132-3.cc
 *** /dev/null	1 Jan 1970 00:00:00 -0000
 --- testsuite/27_io/basic_filebuf/seekpos/10132-3.cc	24 Apr 2003 23:57:56 -=
 0000
 ***************
 *** 0 ****
 --- 1,147 ----
 + // 2003-04-24 bkoz
 +=20
 + // Copyright (C) 2003 Free Software Foundation, Inc.
 + //
 + // This file is part of the GNU ISO C++ Library.  This library is free
 + // software; you can redistribute it and/or modify it under the
 + // terms of the GNU General Public License as published by the
 + // Free Software Foundation; either version 2, or (at your option)
 + // any later version.
 +=20
 + // This library 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.
 +=20
 + // You should have received a copy of the GNU General Public License along
 + // with this library; see the file COPYING.  If not, write to the Free
 + // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-130=
 7,
 + // USA.
 +=20
 + // 27.8.1.1 - Template class basic_filebuf=20
 + // NB: This file is for testing basic_filebuf with NO OTHER INCLUDES.
 +=20
 + #include <fstream>
 + #include <testsuite_hooks.h>
 +=20
 + // libstdc++/10132, add on
 + class gnu_char_type
 + {
 +   unsigned long character;
 + public:
 +   // operator =3D=3D
 +   bool
 +   operator=3D=3D(const gnu_char_type& __lhs)=20
 +   { return character =3D=3D __lhs.character; }
 +=20
 +   // operator <
 +   bool
 +   operator<(const gnu_char_type& __lhs)=20
 +   { return character < __lhs.character; }
 +=20
 +   // default ctor
 +   gnu_char_type() { }
 +=20
 +   // to_char_type
 +   gnu_char_type(const unsigned long& __l) : character(__l) { }=20
 +=20
 +   // to_int_type
 +   operator unsigned long() const { return character; }
 + };
 +=20
 + // char_traits specialization
 + struct gnu_char_traits
 + {
 +   typedef gnu_char_type	char_type;
 +   typedef long  		int_type;
 +   typedef long 		pos_type;
 +   typedef unsigned long 	off_type;
 +   typedef long   		state_type;
 +  =20
 +   static void=20
 +   assign(char_type& __c1, const char_type& __c2) { }
 +  =20
 +   static bool=20
 +   eq(const char_type& __c1, const char_type& __c2) { return true; }
 +  =20
 +   static bool=20
 +   lt(const char_type& __c1, const char_type& __c2) { return true; }
 +  =20
 +   static int=20
 +   compare(const char_type* __s1, const char_type* __s2, size_t __n)
 +   { return 0; }
 +  =20
 +   static size_t
 +   length(const char_type* __s) { return 0; }
 +  =20
 +   static const char_type*=20
 +   find(const char_type* __s, size_t __n, const char_type& __a)
 +   { return __s; }
 +  =20
 +   static char_type*=20
 +   move(char_type* __s1, const char_type* __s2, size_t __n)
 +   { return __s1; }
 +  =20
 +   static char_type*=20
 +   copy(char_type* __s1, const char_type* __s2, size_t __n)
 +   { return __s1; }
 +  =20
 +   static char_type*=20
 +   assign(char_type* __s, size_t __n, char_type __a)
 +   { return __s; }
 +  =20
 +   static char_type=20
 +   to_char_type(const int_type& __c)
 +   { return char_type(); }
 +  =20
 +   static int_type=20
 +   to_int_type(const char_type& __c)
 +   { return int_type(); }
 +  =20
 +   static bool=20
 +   eq_int_type(const int_type& __c1, const int_type& __c2)
 +   { return true; }
 +  =20
 +   static int_type=20
 +   eof()
 +   { return int_type(); }
 +  =20
 +   static int_type=20
 +   not_eof(const int_type& __c)
 +   { return int_type(); }
 + };
 +=20
 + void test07()
 + {
 +   bool test =3D true;
 +   typedef std::basic_filebuf<gnu_char_type, gnu_char_traits> gnu_filebuf;
 +  =20
 +   try
 +     {=20
 +       // Need codecvt facet for width argument in seekpos.
 +       gnu_filebuf obj;
 +       obj.pubseekpos(0);
 +     }
 +   catch(std::exception& obj)
 +     {=20
 +       test =3D false;=20
 +       VERIFY( test );
 +     }
 + }
 +=20
 + #if !__GXX_WEAK__
 + // Explicitly instantiate for systems with no COMDAT or weak support.
 + template=20
 +   std::basic_filebuf<gnu_char_type>::int_type
 +   std::basic_filebuf<gnu_char_type>::_S_pback_size;
 + #endif
 +=20
 + int main()=20
 + {
 +   test07();
 +   return 0;
 + }
 +=20
 +=20
 +=20
 + // more surf!!!



More information about the Gcc-prs mailing list