This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] Fix a bug in basic_stringbuf
- From: Paolo Carlini <pcarlini at suse dot de>
- To: "'gcc-patches at gcc dot gnu dot org'" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 29 Sep 2004 23:16:37 +0200
- Subject: [v3] Fix a bug in basic_stringbuf
Hi,
tested x86/x86_64-linux, committed to mainline.
Paolo.
/////////////
2004-09-29 Paolo Carlini <pcarlini@suse.de>
* include/std/std_sstream.h (basic_stringbuf(ios_base::openmode)):
Don't use _M_stringbuf_init, keep the pointers null, per 27.7.1.1.
(str()): Slightly tweak, protect from pptr() == 0.
(_M_update_egptr()): Likewise.
* include/bits/sstream.tcc (ssekoff, seekpos): In order to check
for an empty buffer use __beg instead of _M_string.capacity().
* testsuite/27_io/basic_stringbuf/cons/char/1.cc: New.
* testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc: Likewise.
* testsuite/27_io/basic_filebuf/cons/char/1.cc: New.
* testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc: Likewise.
* testsuite/27_io/basic_streambuf/cons/char/1.cc: Update.
* testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc: Likewise.
2004-09-29 Paolo Carlini <pcarlini@suse.de>
Benjamin Kosnik <bkoz@redhat.com>
* testsuite/testsuite_io.h (class constraint_buf): New, extended
and templatized version of constraint_filebuf; add typedefs for
streambuf/stringbuf/filebuf and wchar_t counterparts.
diff -prN libstdc++-v3-orig/include/bits/sstream.tcc libstdc++-v3/include/bits/sstream.tcc
*** libstdc++-v3-orig/include/bits/sstream.tcc Fri Aug 13 00:26:31 2004
--- libstdc++-v3/include/bits/sstream.tcc Wed Sep 29 14:38:24 2004
*************** namespace std
*** 123,128 ****
--- 123,129 ----
{
// Update egptr() to match the actual string end.
_M_update_egptr();
+
if (this->gptr() < this->egptr())
__ret = traits_type::to_int_type(*this->gptr());
}
*************** namespace std
*** 141,150 ****
__testin &= !(__mode & ios_base::out);
__testout &= !(__mode & ios_base::in);
! if (_M_string.capacity() && (__testin || __testout || __testboth))
{
- char_type* __beg = __testin ? this->eback() : this->pbase();
-
_M_update_egptr();
off_type __newoffi = __off;
--- 142,150 ----
__testin &= !(__mode & ios_base::out);
__testout &= !(__mode & ios_base::in);
! const char_type* __beg = __testin ? this->eback() : this->pbase();
! if (__beg && (__testin || __testout || __testboth))
{
_M_update_egptr();
off_type __newoffi = __off;
*************** namespace std
*** 181,195 ****
seekpos(pos_type __sp, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
! if (_M_string.capacity())
! {
! off_type __pos (__sp);
! const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
! const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
! char_type* __beg = __testin ? this->eback() : this->pbase();
_M_update_egptr();
const bool __testpos = 0 <= __pos
&& __pos <= this->egptr() - __beg;
if ((__testin || __testout) && __testpos)
--- 181,195 ----
seekpos(pos_type __sp, ios_base::openmode __mode)
{
pos_type __ret = pos_type(off_type(-1));
! const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
! const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
+ const char_type* __beg = __testin ? this->eback() : this->pbase();
+ if (__beg)
+ {
_M_update_egptr();
+ off_type __pos(__sp);
const bool __testpos = 0 <= __pos
&& __pos <= this->egptr() - __beg;
if ((__testin || __testout) && __testpos)
diff -prN libstdc++-v3-orig/include/std/std_sstream.h libstdc++-v3/include/std/std_sstream.h
*** libstdc++-v3-orig/include/std/std_sstream.h Sun May 23 01:46:33 2004
--- libstdc++-v3/include/std/std_sstream.h Wed Sep 29 14:19:46 2004
*************** namespace std
*** 111,118 ****
*/
explicit
basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
! : __streambuf_type(), _M_mode(), _M_string()
! { _M_stringbuf_init(__mode); }
/**
* @brief Starts with an existing string buffer.
--- 111,118 ----
*/
explicit
basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
! : __streambuf_type(), _M_mode(__mode), _M_string()
! { }
/**
* @brief Starts with an existing string buffer.
*************** namespace std
*** 140,147 ****
__string_type
str() const
{
! const bool __testout = this->_M_mode & ios_base::out;
! if (__testout)
{
// The current egptr() may not be the actual string end.
if (this->pptr() > this->egptr())
--- 140,146 ----
__string_type
str() const
{
! if (this->pptr())
{
// The current egptr() may not be the actual string end.
if (this->pptr() > this->egptr())
*************** namespace std
*** 169,175 ****
}
protected:
! // Common initialization code for both ctors goes here.
/**
* @if maint
* @doctodo
--- 168,174 ----
}
protected:
! // Common initialization code goes here.
/**
* @if maint
* @doctodo
*************** namespace std
*** 277,285 ****
_M_update_egptr()
{
const bool __testin = this->_M_mode & ios_base::in;
- const bool __testout = this->_M_mode & ios_base::out;
! if (__testout && this->pptr() > this->egptr())
if (__testin)
this->setg(this->eback(), this->gptr(), this->pptr());
else
--- 276,283 ----
_M_update_egptr()
{
const bool __testin = this->_M_mode & ios_base::in;
! if (this->pptr() && this->pptr() > this->egptr())
if (__testin)
this->setg(this->eback(), this->gptr(), this->pptr());
else
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_filebuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/char/1.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/cons/char/1.cc Wed Sep 29 20:01:11 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29 Paolo Carlini <pcarlini@suse.de>
+
+ // Copyright (C) 2004 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.
+
+ // 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.
+
+ // 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-1307,
+ // USA.
+
+ // 27.8.1.2 basic_filebuf constructors [lib.filebuf.cons]
+
+ #include <fstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ __gnu_test::constraint_filebuf fbuf;
+ VERIFY( fbuf.check_pointers() );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_filebuf/cons/wchar_t/1.cc Wed Sep 29 20:01:24 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29 Paolo Carlini <pcarlini@suse.de>
+
+ // Copyright (C) 2004 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.
+
+ // 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.
+
+ // 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-1307,
+ // USA.
+
+ // 27.8.1.2 basic_filebuf constructors [lib.filebuf.cons]
+
+ #include <fstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ __gnu_test::constraint_wfilebuf fbuf;
+ VERIFY( fbuf.check_pointers() );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_streambuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/char/1.cc Tue Sep 23 22:03:17 2003
--- libstdc++-v3/testsuite/27_io/basic_streambuf/cons/char/1.cc Wed Sep 29 20:00:11 2004
***************
*** 31,99 ****
#include <streambuf>
#include <testsuite_hooks.h>
!
! class testbuf : public std::streambuf
! {
! public:
!
! // Typedefs:
! typedef std::streambuf::traits_type traits_type;
! typedef std::streambuf::char_type char_type;
!
! testbuf(): std::streambuf()
! { }
!
! bool
! check_pointers()
! {
! bool test __attribute__((unused)) = true;
! VERIFY( this->eback() == NULL );
! VERIFY( this->gptr() == NULL );
! VERIFY( this->egptr() == NULL );
! VERIFY( this->pbase() == NULL );
! VERIFY( this->pptr() == NULL );
! VERIFY( this->epptr() == NULL );
! return test;
! }
!
! int_type
! pub_uflow()
! { return (this->uflow()); }
!
! int_type
! pub_overflow(int_type __c = traits_type::eof())
! { return (this->overflow(__c)); }
!
! int_type
! pub_pbackfail(int_type __c)
! { return (this->pbackfail(__c)); }
!
! void
! pub_setg(char* beg, char* cur, char *end)
! { this->setg(beg, cur, end); }
!
! void
! pub_setp(char* beg, char* end)
! { this->setp(beg, end); }
!
! protected:
! int_type
! underflow()
! {
! int_type __retval = traits_type::eof();
! if (this->gptr() < this->egptr())
! __retval = traits_type::not_eof(0);
! return __retval;
! }
! };
void test01()
{
- typedef testbuf::traits_type traits_type;
- typedef testbuf::int_type int_type;
-
bool test __attribute__((unused)) = true;
! testbuf buf01;
// 27.5.2.1 basic_streambuf ctors
// default ctor initializes
--- 31,42 ----
#include <streambuf>
#include <testsuite_hooks.h>
! #include <testsuite_io.h>
void test01()
{
bool test __attribute__((unused)) = true;
! __gnu_test::constraint_streambuf buf01;
// 27.5.2.1 basic_streambuf ctors
// default ctor initializes
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc Sun Jul 11 21:13:56 2004
--- libstdc++-v3/testsuite/27_io/basic_streambuf/cons/wchar_t/1.cc Wed Sep 29 20:18:26 2004
***************
*** 32,100 ****
#include <streambuf>
#include <testsuite_hooks.h>
!
! class testbuf : public std::wstreambuf
! {
! public:
!
! // Typedefs:
! typedef std::wstreambuf::traits_type traits_type;
! typedef std::wstreambuf::char_type char_type;
!
! testbuf(): std::wstreambuf()
! { }
!
! bool
! check_pointers()
! {
! bool test __attribute__((unused)) = true;
! VERIFY( this->eback() == NULL );
! VERIFY( this->gptr() == NULL );
! VERIFY( this->egptr() == NULL );
! VERIFY( this->pbase() == NULL );
! VERIFY( this->pptr() == NULL );
! VERIFY( this->epptr() == NULL );
! return test;
! }
!
! int_type
! pub_uflow()
! { return (this->uflow()); }
!
! int_type
! pub_overflow(int_type __c = traits_type::eof())
! { return (this->overflow(__c)); }
!
! int_type
! pub_pbackfail(int_type __c)
! { return (this->pbackfail(__c)); }
!
! void
! pub_setg(wchar_t* beg, wchar_t* cur, wchar_t* end)
! { this->setg(beg, cur, end); }
!
! void
! pub_setp(wchar_t* beg, wchar_t* end)
! { this->setp(beg, end); }
!
! protected:
! int_type
! underflow()
! {
! int_type __retval = traits_type::eof();
! if (this->gptr() < this->egptr())
! __retval = traits_type::not_eof(0);
! return __retval;
! }
! };
void test01()
{
- typedef testbuf::traits_type traits_type;
- typedef testbuf::int_type int_type;
-
bool test __attribute__((unused)) = true;
! testbuf buf01;
// 27.5.2.1 basic_streambuf ctors
// default ctor initializes
--- 32,43 ----
#include <streambuf>
#include <testsuite_hooks.h>
! #include <testsuite_io.h>
void test01()
{
bool test __attribute__((unused)) = true;
! __gnu_test::constraint_wstreambuf buf01;
// 27.5.2.1 basic_streambuf ctors
// default ctor initializes
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/char/1.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/1.cc Wed Sep 29 20:00:30 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29 Paolo Carlini <pcarlini@suse.de>
+
+ // Copyright (C) 2004 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.
+
+ // 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.
+
+ // 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-1307,
+ // USA.
+
+ // 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons]
+
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ __gnu_test::constraint_stringbuf sbuf;
+ VERIFY( sbuf.check_pointers() );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc Wed Sep 29 20:00:47 2004
***************
*** 0 ****
--- 1,40 ----
+ // 2004-09-29 Paolo Carlini <pcarlini@suse.de>
+
+ // Copyright (C) 2004 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.
+
+ // 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.
+
+ // 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-1307,
+ // USA.
+
+ // 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons]
+
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ #include <testsuite_io.h>
+
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+ bool test __attribute__((unused)) = true;
+
+ __gnu_test::constraint_wstringbuf sbuf;
+ VERIFY( sbuf.check_pointers() );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/testsuite_io.h libstdc++-v3/testsuite/testsuite_io.h
*** libstdc++-v3-orig/testsuite/testsuite_io.h Tue Dec 2 03:48:50 2003
--- libstdc++-v3/testsuite/testsuite_io.h Wed Sep 29 20:01:43 2004
***************
*** 1,7 ****
// -*- C++ -*-
! // Testing filebuf for the C++ library testsuite.
//
! // 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
--- 1,7 ----
// -*- C++ -*-
! // Testing streambuf/filebuf/stringbuf for the C++ library testsuite.
//
! // Copyright (C) 2003, 2004 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
***************
*** 32,37 ****
--- 32,38 ----
#define _GLIBCXX_TESTSUITE_IO_H
#include <fstream>
+ #include <sstream>
namespace __gnu_test
{
*************** namespace __gnu_test
*** 44,77 ****
// Joint file position
// 27.8.1.4 - Overridden virtual functions p9
// If unbuffered, pbase == pptr == NULL
! class constraint_filebuf: public std::filebuf
! {
! public:
! bool
! write_position()
! {
! bool two = this->pptr() != NULL;
! bool one = this->pptr() < this->epptr();
! return one && two;
! }
!
! bool
! read_position()
! {
! bool one = this->gptr() != NULL;
! bool two = this->gptr() < this->egptr();
!
! return one && two;
! }
!
! bool
! unbuffered()
! {
! bool one = this->pbase() == NULL;
! bool two = this->pptr() == NULL;
! return one && two;
! }
! };
// Used to check if basic_streambuf::pubsync() has been called.
// This is useful for checking if a function creates [io]stream::sentry
--- 45,104 ----
// Joint file position
// 27.8.1.4 - Overridden virtual functions p9
// If unbuffered, pbase == pptr == NULL
! // 27.7.1.1 - Basic_stringbuf constructors p 1
! // 27.8.1.2 - Basic_filebuf constructors p 1
! // ... , initializing the base class with basic_streambuf() 27.5.2.1
! template<typename T>
! class constraint_buf
! : public T
! {
! public:
! bool
! write_position()
! {
! bool one = this->pptr() != NULL;
! bool two = this->pptr() < this->epptr();
! return one && two;
! }
!
! bool
! read_position()
! {
! bool one = this->gptr() != NULL;
! bool two = this->gptr() < this->egptr();
! return one && two;
! }
!
! bool
! unbuffered()
! {
! bool one = this->pbase() == NULL;
! bool two = this->pptr() == NULL;
! return one && two;
! }
!
! bool
! check_pointers()
! {
! bool one = this->eback() == NULL;
! bool two = this->gptr() == NULL;
! bool three = this->egptr() == NULL;
!
! bool four = this->pbase() == NULL;
! bool five = this->pptr() == NULL;
! bool six = this->epptr() == NULL;
! return one && two && three && four && five && six;
! }
! };
!
! typedef constraint_buf<std::streambuf> constraint_streambuf;
! typedef constraint_buf<std::filebuf> constraint_filebuf;
! typedef constraint_buf<std::stringbuf> constraint_stringbuf;
! #ifdef _GLIBCXX_USE_WCHAR_T
! typedef constraint_buf<std::wstreambuf> constraint_wstreambuf;
! typedef constraint_buf<std::wfilebuf> constraint_wfilebuf;
! typedef constraint_buf<std::wstringbuf> constraint_wstringbuf;
! #endif
// Used to check if basic_streambuf::pubsync() has been called.
// This is useful for checking if a function creates [io]stream::sentry