From c22bf1992de982d3a48ef24f1be6d9ded41f2ed7 Mon Sep 17 00:00:00 2001
From: paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri, 10 Feb 2006 18:29:04 +0000
Subject: [PATCH] 2006-10-02  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/26181
	* include/bits/streambuf.tcc (__copy_streambufs_eof): New, like
	the existing __copy_streambufs but reporting eof in input.
	(__copy_streambufs): Just use the latter.
	* src/streambuf.cc (__copy_streambufs_eof): Adjust specializations
	of __copy_streambufs.
	* include/bits/istream.tcc (operator>>(__streambuf_type*)): Use
	__copy_streambufs_eof instead.
	* include/std/std_streambuf.h: Adjust.
	* src/streambuf-inst.cc: Adjust.
	* config/abi/pre/gnu.ver: Export the new symbols.
	* testsuite/27_io/basic_istream/extractors_other/char/26181.cc: New.
	* testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc:
	Likewise.
	* testsuite/27_io/basic_istream/extractors_other/char/1.cc: Adjust.
	* testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc:
	Likewise.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110841 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libstdc++-v3/ChangeLog                        | 20 ++++++++
 libstdc++-v3/config/abi/pre/gnu.ver           |  4 +-
 libstdc++-v3/include/bits/istream.tcc         |  5 +-
 libstdc++-v3/include/bits/streambuf.tcc       | 36 ++++++++++---
 libstdc++-v3/include/std/std_streambuf.h      | 19 +++----
 libstdc++-v3/src/streambuf-inst.cc            | 16 ++++--
 libstdc++-v3/src/streambuf.cc                 | 32 ++++++++----
 .../basic_istream/extractors_other/char/1.cc  |  7 +--
 .../extractors_other/char/26181.cc            | 50 +++++++++++++++++++
 .../extractors_other/wchar_t/1.cc             |  6 +--
 .../extractors_other/wchar_t/26181.cc         | 50 +++++++++++++++++++
 11 files changed, 210 insertions(+), 35 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 38ae3c72c743..85fe6bbc679a 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,23 @@
+2006-10-02  Paolo Carlini  <pcarlini@suse.de>
+
+	PR libstdc++/26181
+	* include/bits/streambuf.tcc (__copy_streambufs_eof): New, like
+	the existing __copy_streambufs but reporting eof in input.
+	(__copy_streambufs): Just use the latter.
+	* src/streambuf.cc (__copy_streambufs_eof): Adjust specializations
+	of __copy_streambufs.
+	* include/bits/istream.tcc (operator>>(__streambuf_type*)): Use
+	__copy_streambufs_eof instead.
+	* include/std/std_streambuf.h: Adjust.
+	* src/streambuf-inst.cc: Adjust.
+	* config/abi/pre/gnu.ver: Export the new symbols.
+	* testsuite/27_io/basic_istream/extractors_other/char/26181.cc: New.
+	* testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc:
+	Likewise.
+	* testsuite/27_io/basic_istream/extractors_other/char/1.cc: Adjust.
+	* testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc:
+	Likewise.
+
 2006-02-08  Benjamin Kosnik  <bkoz@redhat.com>
 
 	PR libstdc++/26142
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 8ea7c64a5256..c756290df587 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1,6 +1,6 @@
 ## Linker script for GNU versioning (GNU ld 2.13.91+ only.)
 ##
-## Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 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
@@ -673,6 +673,8 @@ GLIBCXX_3.4.7 {
     _ZNSi10_M_extractI[^g]*;
     _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*;
 
+    _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EEiPSt15basic_streambuf*;
+
 } GLIBCXX_3.4.6;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index 5b5da65aaf5e..ef773bc7080b 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -183,8 +183,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 	{
 	  try
 	    {
-	      if (!__copy_streambufs(this->rdbuf(), __sbout))
+	      bool __ineof;
+	      if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof))
 		__err |= ios_base::failbit;
+	      if (__ineof)
+		__err |= ios_base::eofbit;
 	    }
 	  catch(...)
 	    { this->_M_setstate(ios_base::failbit); }
diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc
index b1a4876fded8..c4b860549a75 100644
--- a/libstdc++-v3/include/bits/streambuf.tcc
+++ b/libstdc++-v3/include/bits/streambuf.tcc
@@ -1,6 +1,6 @@
 // Stream buffer classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -117,22 +117,36 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   // standard.
   template<typename _CharT, typename _Traits>
     streamsize
-    __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
-		      basic_streambuf<_CharT, _Traits>* __sbout)
+    __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin,
+			  basic_streambuf<_CharT, _Traits>* __sbout,
+			  bool& __ineof)
     {
       streamsize __ret = 0;
+      __ineof = true;
       typename _Traits::int_type __c = __sbin->sgetc();
       while (!_Traits::eq_int_type(__c, _Traits::eof()))
 	{
 	  __c = __sbout->sputc(_Traits::to_char_type(__c));
 	  if (_Traits::eq_int_type(__c, _Traits::eof()))
-	    break;
+	    {
+	      __ineof = false;
+	      break;
+	    }
 	  ++__ret;
 	  __c = __sbin->snextc();
 	}
       return __ret;
     }
 
+  template<typename _CharT, typename _Traits>
+    inline streamsize
+    __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
+		      basic_streambuf<_CharT, _Traits>* __sbout)
+    {
+      bool __ineof;
+      return __copy_streambufs_eof(__sbin, __sbout, __ineof);
+    }
+
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.
   // NB:  This syntax is a GNU extension.
@@ -140,13 +154,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   extern template class basic_streambuf<char>;
   extern template
     streamsize
-    __copy_streambufs(basic_streambuf<char>*, basic_streambuf<char>*);
+    __copy_streambufs(basic_streambuf<char>*,
+		      basic_streambuf<char>*);
+  extern template
+    streamsize
+    __copy_streambufs_eof(basic_streambuf<char>*,
+			  basic_streambuf<char>*, bool&);
 
 #ifdef _GLIBCXX_USE_WCHAR_T
   extern template class basic_streambuf<wchar_t>;
   extern template
     streamsize
-    __copy_streambufs(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*);
+    __copy_streambufs(basic_streambuf<wchar_t>*,
+		      basic_streambuf<wchar_t>*);
+  extern template
+    streamsize
+    __copy_streambufs_eof(basic_streambuf<wchar_t>*,
+			  basic_streambuf<wchar_t>*, bool&);
 #endif
 #endif
 
diff --git a/libstdc++-v3/include/std/std_streambuf.h b/libstdc++-v3/include/std/std_streambuf.h
index f59e7deb9a24..b36a139b9782 100644
--- a/libstdc++-v3/include/std/std_streambuf.h
+++ b/libstdc++-v3/include/std/std_streambuf.h
@@ -1,6 +1,6 @@
 // Stream buffer classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -55,8 +55,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   */
   template<typename _CharT, typename _Traits>
     streamsize
-    __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin,
-		      basic_streambuf<_CharT, _Traits>* __sbout);
+    __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin,
+			  basic_streambuf<_CharT, _Traits>* __sbout,
+			  bool& __ineof);
   
   /**
    *  @brief  The actual work of input and output (interface).
@@ -151,8 +152,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       friend class ostreambuf_iterator<char_type, traits_type>;
 
       friend streamsize
-      __copy_streambufs<>(__streambuf_type* __sbin,
-			  __streambuf_type* __sbout);
+      __copy_streambufs_eof<>(__streambuf_type* __sbin,
+			      __streambuf_type* __sbout, bool& __ineof);
       
       template<typename _CharT2, typename _Traits2>
         friend basic_istream<_CharT2, _Traits2>&
@@ -792,13 +793,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   // Explicit specialization declarations, defined in src/streambuf.cc.
   template<>
     streamsize
-    __copy_streambufs(basic_streambuf<char>* __sbin,
-		      basic_streambuf<char>* __sbout);
+    __copy_streambufs_eof(basic_streambuf<char>* __sbin,
+			  basic_streambuf<char>* __sbout, bool& __ineof);
 #ifdef _GLIBCXX_USE_WCHAR_T
   template<>
     streamsize
-    __copy_streambufs(basic_streambuf<wchar_t>* __sbin,
-		      basic_streambuf<wchar_t>* __sbout);
+    __copy_streambufs_eof(basic_streambuf<wchar_t>* __sbin,
+			  basic_streambuf<wchar_t>* __sbout, bool& __ineof);
 #endif
 
 _GLIBCXX_END_NAMESPACE
diff --git a/libstdc++-v3/src/streambuf-inst.cc b/libstdc++-v3/src/streambuf-inst.cc
index d08bc0d2db1f..38fb0d4c3fa9 100644
--- a/libstdc++-v3/src/streambuf-inst.cc
+++ b/libstdc++-v3/src/streambuf-inst.cc
@@ -1,6 +1,6 @@
 // Explicit instantiation file.
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2005
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -42,7 +42,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template
     streamsize
-    __copy_streambufs(basic_streambuf<char>*, basic_streambuf<char>*); 
+    __copy_streambufs(basic_streambuf<char>*, basic_streambuf<char>*);
+
+  template
+    streamsize
+    __copy_streambufs_eof(basic_streambuf<char>*,
+			  basic_streambuf<char>*, bool&);
 
 #ifdef _GLIBCXX_USE_WCHAR_T
   // wstreambuf
@@ -50,7 +55,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template
     streamsize
-    __copy_streambufs(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*); 
+    __copy_streambufs(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*);
+
+  template
+    streamsize
+    __copy_streambufs_eof(basic_streambuf<wchar_t>*,
+			  basic_streambuf<wchar_t>*, bool&);
 #endif
 
 _GLIBCXX_END_NAMESPACE
diff --git a/libstdc++-v3/src/streambuf.cc b/libstdc++-v3/src/streambuf.cc
index 75f61cca4c90..31863145f75c 100644
--- a/libstdc++-v3/src/streambuf.cc
+++ b/libstdc++-v3/src/streambuf.cc
@@ -1,6 +1,6 @@
 // Stream buffer classes -*- C++ -*-
 
-// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005, 2006 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
@@ -37,11 +37,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template<>
     streamsize
-    __copy_streambufs(basic_streambuf<char>* __sbin,
-		      basic_streambuf<char>* __sbout)
+    __copy_streambufs_eof(basic_streambuf<char>* __sbin,
+			  basic_streambuf<char>* __sbout, bool& __ineof)
     {
       typedef basic_streambuf<char>::traits_type traits_type;
       streamsize __ret = 0;
+      __ineof = true;
       traits_type::int_type __c = __sbin->sgetc();
       while (!traits_type::eq_int_type(__c, traits_type::eof()))
 	{
@@ -52,14 +53,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 	      __sbin->gbump(__wrote);
 	      __ret += __wrote;
 	      if (__wrote < __n)
-		break;
+		{
+		  __ineof = false;
+		  break;
+		}
 	      __c = __sbin->underflow();
 	    }
 	  else
 	    {
 	      __c = __sbout->sputc(traits_type::to_char_type(__c));
 	      if (traits_type::eq_int_type(__c, traits_type::eof()))
-		break;
+		{
+		  __ineof = false;
+		  break;
+		}
 	      ++__ret;
 	      __c = __sbin->snextc();
 	    }
@@ -70,11 +77,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 #ifdef _GLIBCXX_USE_WCHAR_T
   template<>
     streamsize
-    __copy_streambufs(basic_streambuf<wchar_t>* __sbin,
-		      basic_streambuf<wchar_t>* __sbout)
+    __copy_streambufs_eof(basic_streambuf<wchar_t>* __sbin,
+			  basic_streambuf<wchar_t>* __sbout, bool& __ineof)
     {
       typedef basic_streambuf<wchar_t>::traits_type traits_type;
       streamsize __ret = 0;
+      __ineof = true;
       traits_type::int_type __c = __sbin->sgetc();
       while (!traits_type::eq_int_type(__c, traits_type::eof()))
 	{
@@ -85,14 +93,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 	      __sbin->gbump(__wrote);
 	      __ret += __wrote;
 	      if (__wrote < __n)
-		break;
+		{
+		  __ineof = false;
+		  break;
+		}
 	      __c = __sbin->underflow();
 	    }
 	  else
 	    {
 	      __c = __sbout->sputc(traits_type::to_char_type(__c));
 	      if (traits_type::eq_int_type(__c, traits_type::eof()))
-		break;
+		{
+		  __ineof = false;
+		  break;
+		}
 	      ++__ret;
 	      __c = __sbin->snextc();
 	    }
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc
index 8994d7397f2f..a2a69bb53caf 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/1.cc
@@ -1,6 +1,7 @@
 // 1999-07-28 bkoz
 
-// Copyright (C) 1999, 2001, 2003 Free Software Foundation
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+// 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
@@ -124,9 +125,9 @@ void test01()
   state1 = is_04.rdstate();
   is_04 >> &isbuf_03;   
   state2 = is_04.rdstate();
-  VERIFY( state1 == state2 );
+  VERIFY( state1 != state2 );
   VERIFY( !static_cast<bool>(state2 & statefail) );
-  VERIFY( state2 != stateeof );
+  VERIFY( state2 == stateeof );
   strtmp = isbuf_03.str();
   VERIFY( strtmp == str_02 ); // as only an "in" buffer
   VERIFY( isbuf_03.sgetc() == 'a' );
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc
new file mode 100644
index 000000000000..b478e9699bbd
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/26181.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2006 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
+// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <istream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/26181
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+  
+  typedef istringstream::pos_type pos_type;
+
+  istringstream iss("Territoires de l'Oubli");
+  ostringstream oss;
+  
+  VERIFY( iss.tellg() == pos_type(0) );
+  
+  iss >> oss.rdbuf();
+  VERIFY( iss.rdstate() == iss.eofbit );
+  
+  iss.clear();
+  VERIFY( iss.tellg() == pos_type(22) );
+  
+  iss.get();
+  VERIFY( iss.tellg() == pos_type(-1) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc
index 8c59d46553d5..1766169fea7b 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/1.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2004 Free Software Foundation
+// Copyright (C) 2004, 2005, 2006 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
@@ -122,9 +122,9 @@ void test01()
   state1 = is_04.rdstate();
   is_04 >> &isbuf_03;   
   state2 = is_04.rdstate();
-  VERIFY( state1 == state2 );
+  VERIFY( state1 != state2 );
   VERIFY( !static_cast<bool>(state2 & statefail) );
-  VERIFY( state2 != stateeof );
+  VERIFY( state2 == stateeof );
   strtmp = isbuf_03.str();
   VERIFY( strtmp == str_02 ); // as only an "in" buffer
   VERIFY( isbuf_03.sgetc() == L'a' );
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc
new file mode 100644
index 000000000000..4fbace705b17
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/26181.cc
@@ -0,0 +1,50 @@
+// Copyright (C) 2006 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
+// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <istream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/26181
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+  
+  typedef wistringstream::pos_type pos_type;
+
+  wistringstream iss(L"Territoires de l'Oubli");
+  wostringstream oss;
+  
+  VERIFY( iss.tellg() == pos_type(0) );
+  
+  iss >> oss.rdbuf();
+  VERIFY( iss.rdstate() == iss.eofbit );
+  
+  iss.clear();
+  VERIFY( iss.tellg() == pos_type(22) );
+  
+  iss.get();
+  VERIFY( iss.tellg() == pos_type(-1) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
-- 
GitLab