Patchwork [v3] Fix libstdc++/47921

login
register
mail settings
Submitter Paolo Carlini
Date Feb. 28, 2011, 11:53 p.m.
Message ID <4D6C3580.4030509@oracle.com>
Download mbox | patch
Permalink /patch/84871/
State New
Headers show

Comments

Paolo Carlini - Feb. 28, 2011, 11:53 p.m.
Hi,

We have to work around the limitation of basic_streambuf<>::pbump of
taking an int, instead of a larger type. Tested x86_64-linux, committed
to mainline.

Many thanks to Jon for having noticed the deeper issue we had.

Thanks,
Paolo.

/////////////////////
2011-02-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/47921
	* include/std/streambuf (basic_streambuf<>::__safe_gbump,
	__safe_pbump): Add.
	* include/bits/streambuf.tcc (basic_streambuf<>::xgetn,
	xputn): Use the latter.
	* include/bits/streambuf_iterator.h: Likewise.
	* src/strstream.cc: Likewise.
	* src/streambuf.cc: Likewise.
	* src/compatibility.cc: Likewise.
	* src/istream.cc: Likewise.
	* include/bits/fstream.tcc (basic_filebuf<>::xsgetn): Use setg
	instead of gbump.
	* include/std/sstream (basic_stringbuf<>::_M_pbump): Add.
	* include/bits/sstream.tcc (basic_stringbuf<>::seekoff,
	seekpos, _M_sync): Use setg, setp, and _M_pbump.
	* config/abi/pre/gnu.ver: Tweak.

Patch

Index: src/strstream.cc
===================================================================
--- src/strstream.cc	(revision 170567)
+++ src/strstream.cc	(working copy)
@@ -1,6 +1,7 @@ 
 // strstream definitions -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation
+// Copyright (C) 2001, 2002, 2003, 2005, 2009, 2010, 2011
+// Free Software Foundation
 //
 // 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
@@ -161,7 +162,7 @@ 
 	      }
 	    
 	    setp(buf, buf + new_size);
-	    pbump(old_size);
+	    __safe_pbump(old_size);
 
 	    if (reposition_get)
 	      setg(buf, buf + old_get_offset, buf + 
@@ -271,12 +272,12 @@ 
 	if (seeklow + off < pbase()) 
 	  {
 	    setp(seeklow, epptr());
-	    pbump(off);
+	    __safe_pbump(off);
 	  }
 	else 
 	  {
 	    setp(pbase(), epptr());
-	    pbump(off - (pbase() - seeklow));
+	    __safe_pbump(off - (pbase() - seeklow));
 	  }
       }
     if (do_get) 
Index: src/streambuf.cc
===================================================================
--- src/streambuf.cc	(revision 170567)
+++ src/streambuf.cc	(working copy)
@@ -1,6 +1,7 @@ 
 // Stream buffer classes -*- C++ -*-
 
-// Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+// 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
@@ -47,7 +48,7 @@ 
 	  if (__n > 1)
 	    {
 	      const streamsize __wrote = __sbout->sputn(__sbin->gptr(), __n);
-	      __sbin->gbump(__wrote);
+	      __sbin->__safe_gbump(__wrote);
 	      __ret += __wrote;
 	      if (__wrote < __n)
 		{
@@ -87,7 +88,7 @@ 
 	  if (__n > 1)
 	    {
 	      const streamsize __wrote = __sbout->sputn(__sbin->gptr(), __n);
-	      __sbin->gbump(__wrote);
+	      __sbin->__safe_gbump(__wrote);
 	      __ret += __wrote;
 	      if (__wrote < __n)
 		{
Index: src/compatibility.cc
===================================================================
--- src/compatibility.cc	(revision 170567)
+++ src/compatibility.cc	(working copy)
@@ -86,7 +86,7 @@ 
 					          streamsize(__n - _M_gcount));
 		      if (__size > 1)
 			{
-			  __sb->gbump(__size);
+			  __sb->__safe_gbump(__size);
 			  _M_gcount += __size;
 			  __c = __sb->sgetc();
 			}
@@ -157,7 +157,7 @@ 
 						  streamsize(__n - _M_gcount));
 		      if (__size > 1)
 			{
-			  __sb->gbump(__size);
+			  __sb->__safe_gbump(__size);
 			  _M_gcount += __size;
 			  __c = __sb->sgetc();
 			}
Index: src/istream.cc
===================================================================
--- src/istream.cc	(revision 170567)
+++ src/istream.cc	(working copy)
@@ -67,7 +67,7 @@ 
 			__size = __p - __sb->gptr();
 		      traits_type::copy(__s, __sb->gptr(), __size);
 		      __s += __size;
-		      __sb->gbump(__size);
+		      __sb->__safe_gbump(__size);
 		      _M_gcount += __size;
 		      __c = __sb->sgetc();
 		    }
@@ -145,7 +145,7 @@ 
 								   __cdelim);
 			  if (__p)
 			    __size = __p - __sb->gptr();
-			  __sb->gbump(__size);
+			  __sb->__safe_gbump(__size);
 			  _M_gcount += __size;
 			  __c = __sb->sgetc();
 			}
@@ -239,7 +239,7 @@ 
 				- __sb->gptr());
 		      __traits_type::copy(__s, __sb->gptr(), __size);
 		      __s += __size;
-		      __sb->gbump(__size);
+		      __sb->__safe_gbump(__size);
 		      __extracted += __size;
 		      __c = __sb->sgetc();
 		    }
@@ -318,7 +318,7 @@ 
 					     __sb->gptr() + __size)
 				- __sb->gptr());
 		      __str.append(__sb->gptr(), __size);
-		      __sb->gbump(__size);
+		      __sb->__safe_gbump(__size);
 		      __extracted += __size;
 		      __c = __sb->sgetc();
 		    }
@@ -397,7 +397,7 @@ 
 		      if (__p)
 			__size = __p - __sb->gptr();
 		      __str.append(__sb->gptr(), __size);
-		      __sb->gbump(__size);
+		      __sb->__safe_gbump(__size);
 		      __extracted += __size;
 		      __c = __sb->sgetc();
 		    }
@@ -474,7 +474,7 @@ 
 			__size = __p - __sb->gptr();
 		      traits_type::copy(__s, __sb->gptr(), __size);
 		      __s += __size;
-		      __sb->gbump(__size);
+		      __sb->__safe_gbump(__size);
 		      _M_gcount += __size;
 		      __c = __sb->sgetc();
 		    }
@@ -552,7 +552,7 @@ 
 								   __cdelim);
 			  if (__p)
 			    __size = __p - __sb->gptr();
-			  __sb->gbump(__size);
+			  __sb->__safe_gbump(__size);
 			  _M_gcount += __size;
 			  __c = __sb->sgetc();
 			}
@@ -643,7 +643,7 @@ 
 		      if (__p)
 			__size = __p - __sb->gptr();
 		      __str.append(__sb->gptr(), __size);
-		      __sb->gbump(__size);
+		      __sb->__safe_gbump(__size);
 		      __extracted += __size;
 		      __c = __sb->sgetc();
 		    }
Index: include/std/streambuf
===================================================================
--- include/std/streambuf	(revision 170570)
+++ include/std/streambuf	(working copy)
@@ -769,6 +769,13 @@ 
       }
 #endif
 
+      // Also used by specializations for char and wchar_t in src.
+      void 
+      __safe_gbump(streamsize __n) { _M_in_cur += __n; }
+
+      void
+      __safe_pbump(streamsize __n) { _M_out_cur += __n; }
+
     private:
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // Side effect of DR 50. 
Index: include/std/sstream
===================================================================
--- include/std/sstream	(revision 170570)
+++ include/std/sstream	(working copy)
@@ -241,6 +241,11 @@ 
 	      this->setg(this->pptr(), this->pptr(), this->pptr());
 	  }
       }
+
+      // Works around the issue with pbump, part of the protected
+      // interface of basic_streambuf, taking just an int.
+      void
+      _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
     };
 
 
Index: include/bits/sstream.tcc
===================================================================
--- include/bits/sstream.tcc	(revision 170567)
+++ include/bits/sstream.tcc	(working copy)
@@ -1,7 +1,7 @@ 
 // String based streams -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2009, 2010
+// 2006, 2007, 2008, 2009, 2010, 2011
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -178,14 +178,15 @@ 
 	      && __newoffi >= 0
 	      && this->egptr() - __beg >= __newoffi)
 	    {
-	      this->gbump((__beg + __newoffi) - this->gptr());
+	      this->setg(this->eback(), this->eback() + __newoffi,
+			 this->egptr());
 	      __ret = pos_type(__newoffi);
 	    }
 	  if ((__testout || __testboth)
 	      && __newoffo >= 0
 	      && this->egptr() - __beg >= __newoffo)
 	    {
-	      this->pbump((__beg + __newoffo) - this->pptr());
+	      _M_pbump(this->pbase(), this->epptr(), __newoffo);
 	      __ret = pos_type(__newoffo);
 	    }
 	}
@@ -212,9 +213,10 @@ 
 	  if (__testpos)
 	    {
 	      if (__testin)
-		this->gbump((__beg + __pos) - this->gptr());
+		this->setg(this->eback(), this->eback() + __pos,
+			   this->egptr());
 	      if (__testout)
-                this->pbump((__beg + __pos) - this->pptr());
+		_M_pbump(this->pbase(), this->epptr(), __pos);
 	      __ret = __sp;
 	    }
 	}
@@ -243,8 +245,7 @@ 
 	this->setg(__base, __base + __i, __endg);
       if (__testout)
 	{
-	  this->setp(__base, __endp);
-	  this->pbump(__o);
+	  _M_pbump(__base, __endp, __o);
 	  // egptr() always tracks the string end.  When !__testin,
 	  // for the correct functioning of the streambuf inlines
 	  // the other get area pointers are identical.
@@ -253,6 +254,20 @@ 
 	}
     }
 
+  template <class _CharT, class _Traits, class _Alloc>
+    void
+    basic_stringbuf<_CharT, _Traits, _Alloc>::
+    _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off)
+    {
+      this->setp(__pbeg, __pend);
+      while (__off > __gnu_cxx::__numeric_traits<int>::__max)
+	{
+	  this->pbump(__gnu_cxx::__numeric_traits<int>::__max);
+	  __off -= __gnu_cxx::__numeric_traits<int>::__max;
+	}
+      this->pbump(__off);
+    }
+
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.
   // NB:  This syntax is a GNU extension.
Index: include/bits/streambuf_iterator.h
===================================================================
--- include/bits/streambuf_iterator.h	(revision 170567)
+++ include/bits/streambuf_iterator.h	(working copy)
@@ -1,7 +1,7 @@ 
 // Streambuf iterators
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2009, 2010
+// 2006, 2007, 2009, 2010, 2011
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -339,7 +339,7 @@ 
 	      if (__n > 1)
 		{
 		  traits_type::copy(__result, __sb->gptr(), __n);
-		  __sb->gbump(__n);
+		  __sb->__safe_gbump(__n);
 		  __result += __n;
 		  __c = __sb->underflow();
 		}
@@ -379,7 +379,7 @@ 
 							__n, __val);
 		  if (__p)
 		    __n = __p - __sb->gptr();
-		  __sb->gbump(__n);
+		  __sb->__safe_gbump(__n);
 		  __c = __sb->sgetc();
 		}
 	      else
Index: include/bits/streambuf.tcc
===================================================================
--- include/bits/streambuf.tcc	(revision 170567)
+++ include/bits/streambuf.tcc	(working copy)
@@ -1,7 +1,7 @@ 
 // Stream buffer classes -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2009, 2010  Free Software Foundation, Inc.
+// 2006, 2007, 2008, 2009, 2010, 2011  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
@@ -57,7 +57,7 @@ 
 	      traits_type::copy(__s, this->gptr(), __len);
 	      __ret += __len;
 	      __s += __len;
-	      this->gbump(__len);
+	      this->__safe_gbump(__len);
 	    }
 
 	  if (__ret < __n)
@@ -91,7 +91,7 @@ 
 	      traits_type::copy(this->pptr(), __s, __len);
 	      __ret += __len;
 	      __s += __len;
-	      this->pbump(__len);
+	      this->__safe_pbump(__len);
 	    }
 
 	  if (__ret < __n)
Index: include/bits/fstream.tcc
===================================================================
--- include/bits/fstream.tcc	(revision 170567)
+++ include/bits/fstream.tcc	(working copy)
@@ -584,14 +584,12 @@ 
  	   const streamsize __avail = this->egptr() - this->gptr();
  	   if (__avail != 0)
  	     {
- 	       if (__avail == 1)
- 		 *__s = *this->gptr();
- 	       else
- 		 traits_type::copy(__s, this->gptr(), __avail);
+	       traits_type::copy(__s, this->gptr(), __avail);
  	       __s += __avail;
- 	       this->gbump(__avail);
- 	       __ret += __avail;
- 	       __n -= __avail;
+	       this->setg(this->eback(), this->gptr() + __avail,
+			  this->egptr());
+	       __ret += __avail;
+	       __n -= __avail;
  	     }
  
  	   // Need to loop in case of short reads (relatively common
Index: config/abi/pre/gnu.ver
===================================================================
--- config/abi/pre/gnu.ver	(revision 170567)
+++ config/abi/pre/gnu.ver	(working copy)
@@ -322,7 +322,8 @@ 
     _ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strERKSs;
     _ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strERKSbIwS1_S2_E;
     _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9][t-z]*;
-    _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]_M_[a-z]*;
+    _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]_M_[a-o]*;
+    _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]_M_[q-z]*;
     _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9][0-9]_M_[a-z]*;
 
     # std::basic_iostream constructors, destructors