From patchwork Mon Feb 28 23:53:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 84871 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 677F6B70B8 for ; Tue, 1 Mar 2011 10:53:53 +1100 (EST) Received: (qmail 13759 invoked by alias); 28 Feb 2011 23:53:49 -0000 Received: (qmail 13741 invoked by uid 22791); 28 Feb 2011 23:53:47 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from smtp207.alice.it (HELO smtp207.alice.it) (82.57.200.103) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 28 Feb 2011 23:53:40 +0000 Received: from [192.168.1.4] (79.47.194.33) by smtp207.alice.it (8.5.124.08) id 4C9E16C90CD34A44; Tue, 1 Mar 2011 00:53:37 +0100 Message-ID: <4D6C3580.4030509@oracle.com> Date: Tue, 01 Mar 2011 00:53:36 +0100 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20101125 SUSE/3.0.11 Thunderbird/3.0.11 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: libstdc++ Subject: [v3] Fix libstdc++/47921 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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. 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 + 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::__max) + { + this->pbump(__gnu_cxx::__numeric_traits::__max); + __off -= __gnu_cxx::__numeric_traits::__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