diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 26 | ||||
-rw-r--r-- | libstdc++-v3/config/abi/pre/gnu.ver | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/fstream.tcc | 100 | ||||
-rw-r--r-- | libstdc++-v3/include/std/fstream | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/45628-2.cc | 103 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/4.cc | 20 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc | 79 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc | 20 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_filebuf/sync/char/1.cc | 51 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc | 51 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/util/testsuite_character.h | 4 |
11 files changed, 329 insertions, 141 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8f5dc71..551b23f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,29 @@ +2010-09-22 David Krauss <potswa@mac.com> + + PR libstdc++/45628 + * include/bits/fstream.tcc (basic_filebuf::underflow): Add state + transition to avoid modality requiring seekoff(0,ios::cur). + (basic_filebuf::pbackfail): Likewise. + (basic_filebuf::overflow): Likewise. + (basic_filebuf::_M_seek): Avoid minor unnecessary conversion. + (basic_filebuf::seekoff): Remove code to _M_get_ext_pos; make + (0, ios::cur) a special case preserving buffer contents. + (basic_filebuf::_M_get_ext_pos): New function to obtain status + about codecvt extern_t buffer for overflow and seekoff. + * include/std/fstream (basic_filebuf::_M_get_ext_pos): Likewise. + * config/abi/pre/gnu.ver: Export new symbols. + * testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc: New, + verifies that seekoff(0, ios::cur) preserves buffers. + * testsuite/27_io/basic_filebuf/seekoff/char/45628-2.cc: Likewise. + for codecvt case. More lenient as it may still flush put area. + * testsuite/27_io/basic_filebuf/seekoff/char/4.cc: Modify to + check that seekoff is not required between read and write. + * testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc: Likewise. + * testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc: Remove. + * testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc: Likewise. + * testsuite/util/testsuite_character.h (codecvt::do_length): Comply + with 22.2.1.5.2/10 "Returns ... the LARGEST value in the range..." + 2010-09-22 Paolo Carlini <paolo.carlini@oracle.com> * include/bits/functional_hash.h (__hash_base): Add. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 435f857..4981ca9 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -332,7 +332,13 @@ GLIBCXX_3.4 { # std::basic_filebuf _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EEC*; _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EED*; - _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE[0-3]*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE0*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE13*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE15*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE16*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE19*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE2*; + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE3*; _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE4openEPKc*; _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE4sync*; _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE[5-9]*; @@ -1178,6 +1184,9 @@ GLIBCXX_3.4.15 { _ZNSbIwSt11char_traitsIwESaIwEE4backEv; _ZNKSbIwSt11char_traitsIwESaIwEE4backEv; + # basic_filebuf::_M_get_ext_pos + _ZNSt13basic_filebufI[cw]St11char_traitsI[cw]EE14_M_get_ext_pos*; + } GLIBCXX_3.4.14; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index c498f48..2f661eb 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -1,7 +1,7 @@ // File based streams -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -// 2007, 2008, 2009 +// 2007, 2008, 2009, 2010 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -205,8 +205,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { int_type __ret = traits_type::eof(); const bool __testin = _M_mode & ios_base::in; - if (__testin && !_M_writing) + if (__testin) { + if (_M_writing) + { + __ret = overflow(); + if (__ret == traits_type::eof()) + return __ret; + _M_set_buffer(-1); + _M_writing = false; + } // Check for pback madness, and if so switch back to the // normal buffers and jet outta here before expensive // fileops happen... @@ -357,8 +365,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { int_type __ret = traits_type::eof(); const bool __testin = _M_mode & ios_base::in; - if (__testin && !_M_writing) + if (__testin) { + if (_M_writing) + { + __ret = overflow(); + if (__ret == traits_type::eof()) + return __ret; + _M_set_buffer(-1); + _M_writing = false; + } // Remember whether the pback buffer is active, otherwise below // we may try to store in it a second char (libstdc++/9761). const bool __testpb = _M_pback_init; @@ -410,8 +426,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) int_type __ret = traits_type::eof(); const bool __testeof = traits_type::eq_int_type(__c, __ret); const bool __testout = _M_mode & ios_base::out; - if (__testout && !_M_reading) + if (__testout) { + if (_M_reading) + { + _M_destroy_pback(); + const int __gptr_off = _M_get_ext_pos(_M_state_last); + if (_M_seek(__gptr_off, ios_base::cur, _M_state_last) + == pos_type(off_type(-1))) + return __ret; + } if (this->pbase() < this->pptr()) { // If appropriate, append the overflow char. @@ -691,12 +715,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std) if (__width < 0) __width = 0; - pos_type __ret = pos_type(off_type(-1)); + pos_type __ret = pos_type(off_type(-1)); const bool __testfail = __off != 0 && __width <= 0; if (this->is_open() && !__testfail) { + // tellg and tellp queries do not affect any state, unless + // ! always_noconv and the put sequence is not empty. + // In that case, determining the position requires converting the + // put sequence. That doesn't use ext_buf, so requires a flush. + bool __no_movement = __way == ios_base::cur && __off == 0 + && (!_M_writing || _M_codecvt->always_noconv()); + // Ditch any pback buffers to avoid confusion. - _M_destroy_pback(); + if (!__no_movement) + _M_destroy_pback(); // Correct state at destination. Note that this is the correct // state for the current position during output, because @@ -707,24 +739,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) off_type __computed_off = __off * __width; if (_M_reading && __way == ios_base::cur) { - if (_M_codecvt->always_noconv()) - __computed_off += this->gptr() - this->egptr(); - else + __state = _M_state_last; + __computed_off += _M_get_ext_pos(__state); + } + if (!__no_movement) + __ret = _M_seek(__computed_off, __way, __state); + else + { + if (_M_writing) + __computed_off = this->pptr() - this->pbase(); + + off_type __file_off = _M_file.seekoff(0, ios_base::cur); + if (__file_off != off_type(-1)) { - // Calculate offset from _M_ext_buf that corresponds - // to gptr(). Note: uses _M_state_last, which - // corresponds to eback(). - const int __gptr_off = - _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, - this->gptr() - this->eback()); - __computed_off += _M_ext_buf + __gptr_off - _M_ext_end; - - // _M_state_last is modified by codecvt::length() so - // it now corresponds to gptr(). - __state = _M_state_last; + __ret = __file_off + __computed_off; + __ret.state(__state); } } - __ret = _M_seek(__computed_off, __way, __state); } return __ret; } @@ -756,21 +787,42 @@ _GLIBCXX_BEGIN_NAMESPACE(std) pos_type __ret = pos_type(off_type(-1)); if (_M_terminate_output()) { - // Returns pos_type(off_type(-1)) in case of failure. - __ret = pos_type(_M_file.seekoff(__off, __way)); - if (__ret != pos_type(off_type(-1))) + off_type __file_off = _M_file.seekoff(__off, __way); + if (__file_off != off_type(-1)) { _M_reading = false; _M_writing = false; _M_ext_next = _M_ext_end = _M_ext_buf; _M_set_buffer(-1); _M_state_cur = __state; + __ret = __file_off; __ret.state(_M_state_cur); } } return __ret; } + // Returns the distance from the end of the ext buffer to the point + // corresponding to gptr(). This is a negative value. Updates __state + // from eback() correspondence to gptr(). + template<typename _CharT, typename _Traits> + int basic_filebuf<_CharT, _Traits>:: + _M_get_ext_pos(__state_type& __state) + { + if (_M_codecvt->always_noconv()) + return this->gptr() - this->egptr(); + else + { + // Calculate offset from _M_ext_buf that corresponds to + // gptr(). Precondition: __state == _M_state_last, which + // corresponds to eback(). + const int __gptr_off = + _M_codecvt->length(__state, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + return _M_ext_buf + __gptr_off - _M_ext_end; + } + } + template<typename _CharT, typename _Traits> bool basic_filebuf<_CharT, _Traits>:: diff --git a/libstdc++-v3/include/std/fstream b/libstdc++-v3/include/std/fstream index 00690be..0ffd33d 100644 --- a/libstdc++-v3/include/std/fstream +++ b/libstdc++-v3/include/std/fstream @@ -351,9 +351,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); - // Common code for seekoff and seekpos + // Common code for seekoff, seekpos, and overflow pos_type _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); + + int + _M_get_ext_pos(__state_type &__state); virtual int sync(); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/45628-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/45628-2.cc new file mode 100644 index 0000000..6e40a89 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/45628-2.cc @@ -0,0 +1,103 @@ +// Copyright (C) 2010 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 3, 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 COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <fstream> +#include <testsuite_hooks.h> +#include <testsuite_character.h> + +const char name_01[] = "tmp_seekoff_45628.tst"; + +unsigned underflows, overflows; + +class my_filebuf +: public std::basic_filebuf<__gnu_test::pod_uchar> +{ + virtual int_type + underflow() + { + ++underflows; + return std::basic_filebuf<__gnu_test::pod_uchar>::underflow(); + } + virtual int_type + overflow(int_type c) + { + ++overflows; + return std::basic_filebuf<__gnu_test::pod_uchar>::overflow(c); + } +}; + +// libstdc++/45628 +void test01() +{ + bool test __attribute__((unused)) = true; + + using __gnu_test::pod_uchar; + std::locale loc(std::locale::classic(), + new std::codecvt<my_filebuf::traits_type::char_type, char, + my_filebuf::traits_type::state_type>); + + my_filebuf::pos_type opos[3], ipos[3]; + my_filebuf q; + q.pubimbue(loc); + + q.open(name_01, std::ios_base::in | std::ios_base::out + | std::ios_base::trunc); + + q.sputc(pod_uchar::from<char>('a')); + opos[0] = q.pubseekoff(0, std::ios_base::cur); + q.sputc(pod_uchar::from<char>('b')); + opos[1] = q.pubseekoff(0, std::ios_base::cur); + q.sputc(pod_uchar::from<char>('c')); + opos[2] = q.pubseekoff(0, std::ios_base::cur); + + VERIFY( overflows <= 9 ); // pubseekoff calls overflow twice if converting. + // NB: checking opos==ipos is not very rigorous as long as it flushes, since + // all positions will be at initial state. + q.pubseekoff(0, std::ios_base::beg); + + q.sbumpc(); + VERIFY( underflows == 1 ); + + ipos[0] = q.pubseekoff(0, std::ios_base::cur); + VERIFY( ipos[0] == opos[0] ); + q.sbumpc(); + ipos[1] = q.pubseekoff(0, std::ios_base::cur); + VERIFY( ipos[1] == opos[1] ); + q.sbumpc(); + ipos[2] = q.pubseekoff(0, std::ios_base::cur); + VERIFY( ipos[2] == opos[2] ); + + VERIFY( underflows == 1 ); // pubseekoff never flushes get area + + // Bonus test: check automatic mode switches. + q.sputc(pod_uchar::from<char>('d')); + + q.pubseekpos( ipos[1] ); + q.sputc(pod_uchar::from<char>('e')); + + VERIFY( my_filebuf::traits_type::eq( + my_filebuf::traits_type::to_char_type(q.sgetc()), + pod_uchar::from<char>('d')) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/4.cc index 9422f29..fe21b3a 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/4.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/4.cc @@ -31,7 +31,7 @@ void test01() typedef filebuf::pos_type pos_type; const char name[] = "tmp_seekoff-4.tst"; - const size_t size = 10; + const size_t size = 12; char buf[size]; streamsize n; @@ -46,7 +46,7 @@ void test01() VERIFY( n == 3 ); VERIFY( !memcmp(buf, "abc", 3) ); - fb.pubseekoff(0, ios_base::cur); + // Check read => write without pubseekoff(0, ios_base::cur) n = fb.sputn("ef", 2); VERIFY( n == 2 ); @@ -58,9 +58,17 @@ void test01() VERIFY( !memcmp(buf, "abcef", 5) ); fb.pubseekoff(0, ios_base::beg); - n = fb.sputn("ghijkl", 6); - VERIFY( n == 6 ); + n = fb.sputn("gh", 2); + VERIFY( n == 2 ); + + // Check write => read without pubseekoff(0, ios_base::cur) + + n = fb.sgetn( buf, 3 ); + VERIFY( !memcmp(buf, "cef", 3) ); + n = fb.sputn("ijkl", 4); + VERIFY( n == 4 ); + fb.pubseekoff(0, ios_base::beg); n = fb.sgetn(buf, 2); VERIFY( n == 2 ); @@ -72,8 +80,8 @@ void test01() fb.pubseekoff(0, ios_base::beg); n = fb.sgetn(buf, size); - VERIFY( n == 9 ); - VERIFY( !memcmp(buf, "ghijklmno", 9) ); + VERIFY( n == 12 ); + VERIFY( !memcmp(buf, "ghcefijklmno", 12) ); fb.close(); } diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc new file mode 100644 index 0000000..a80a338 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/char/45628-1.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2010 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 3, 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 COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <fstream> +#include <testsuite_hooks.h> + +const char name_01[] = "tmp_seekoff_45628.tst"; + +unsigned underflows, overflows; + +class my_filebuf +: public std::filebuf +{ + virtual int_type + underflow() + { + ++underflows; + return std::filebuf::underflow(); + } + virtual int_type + overflow(int_type c) + { + ++overflows; + return std::filebuf::overflow(c); + } +}; + +// libstdc++/45628 +void test01() +{ + bool test __attribute__((unused)) = true; + + my_filebuf q; + q.open(name_01, std::ios_base::in | std::ios_base::out + | std::ios_base::trunc); + + q.sputc('a'); + q.pubseekoff(0, std::ios_base::cur); + q.sputc('b'); + q.pubseekoff(0, std::ios_base::cur); + q.sputc('c'); + q.pubseekoff(0, std::ios_base::cur); + + VERIFY( overflows <= 1 ); // only initial sputc allowed to overflow + q.pubseekoff(0, std::ios_base::beg); + + q.sbumpc(); + VERIFY( underflows == 1 ); + + q.pubseekoff(0, std::ios_base::cur); + q.sbumpc(); + q.pubseekoff(0, std::ios_base::cur); + q.sbumpc(); + q.pubseekoff(0, std::ios_base::cur); + + VERIFY( underflows == 1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc index 95338cf..a6bba98 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/seekoff/wchar_t/4.cc @@ -31,7 +31,7 @@ void test01() typedef wfilebuf::pos_type pos_type; const char name[] = "tmp_seekoff-4.tst"; - const size_t size = 10; + const size_t size = 12; wchar_t buf[size]; streamsize n; @@ -46,7 +46,7 @@ void test01() VERIFY( n == 3 ); VERIFY( !wmemcmp(buf, L"abc", 3) ); - fb.pubseekoff(0, ios_base::cur); + // Check read => write without pubseekoff(0, ios_base::cur) n = fb.sputn(L"ef", 2); VERIFY( n == 2 ); @@ -58,8 +58,16 @@ void test01() VERIFY( !wmemcmp(buf, L"abcef", 5) ); fb.pubseekoff(0, ios_base::beg); - n = fb.sputn(L"ghijkl", 6); - VERIFY( n == 6 ); + n = fb.sputn(L"gh", 2); + VERIFY( n == 2 ); + + // Check write => read without pubseekoff(0, ios_base::cur) + + n = fb.sgetn( buf, 3 ); + VERIFY( !memcmp(buf, L"cef", 3) ); + + n = fb.sputn(L"ijkl", 4); + VERIFY( n == 4 ); fb.pubseekoff(0, ios_base::beg); n = fb.sgetn(buf, 2); @@ -72,8 +80,8 @@ void test01() fb.pubseekoff(0, ios_base::beg); n = fb.sgetn(buf, size); - VERIFY( n == 9 ); - VERIFY( !wmemcmp(buf, L"ghijklmno", 9) ); + VERIFY( n == 12 ); + VERIFY( !wmemcmp(buf, L"ghcefijklmno", 12) ); fb.close(); } diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sync/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sync/char/1.cc deleted file mode 100644 index 0a11c43..0000000 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/sync/char/1.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2003, 2009 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 3, 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 COPYING3. If not see -// <http://www.gnu.org/licenses/>. - -// 27.8.1.4 Overridden virtual functions - -#include <fstream> -#include <testsuite_hooks.h> - -void test01() -{ - using namespace std; - - bool test __attribute__((unused)) = true; - const char* name = "tmp_sync_1"; - - filebuf fb; - - fb.open(name, ios_base::in | ios_base::out | ios_base::trunc); - fb.sputn("abc", 3); - - fb.pubseekoff(0, ios_base::beg); - fb.sputc('1'); - - // Sync can't be used to switch from write mode to read mode. - fb.pubsync(); - - filebuf::int_type c = fb.sbumpc(); - VERIFY( c == filebuf::traits_type::eof() ); - - fb.close(); -} - -int main() -{ - test01(); - return 0; -} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc deleted file mode 100644 index a64f455..0000000 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/sync/wchar_t/1.cc +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2003, 2009 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 3, 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 COPYING3. If not see -// <http://www.gnu.org/licenses/>. - -// 27.8.1.4 Overridden virtual functions - -#include <fstream> -#include <testsuite_hooks.h> - -void test01() -{ - using namespace std; - - bool test __attribute__((unused)) = true; - const char* name = "tmp_sync_1"; - - wfilebuf fb; - - fb.open(name, ios_base::in | ios_base::out | ios_base::trunc); - fb.sputn(L"abc", 3); - - fb.pubseekoff(0, ios_base::beg); - fb.sputc(L'1'); - - // Sync can't be used to switch from write mode to read mode. - fb.pubsync(); - - wfilebuf::int_type c = fb.sbumpc(); - VERIFY( c == wfilebuf::traits_type::eof() ); - - fb.close(); -} - -int main() -{ - test01(); - return 0; -} diff --git a/libstdc++-v3/testsuite/util/testsuite_character.h b/libstdc++-v3/testsuite/util/testsuite_character.h index 35ccfa8..ceda1f5 100644 --- a/libstdc++-v3/testsuite/util/testsuite_character.h +++ b/libstdc++-v3/testsuite/util/testsuite_character.h @@ -294,7 +294,7 @@ namespace std const extern_type* end, size_t max) const { const extern_type* beg = from; - while (from < end && max) + while (from < end) { unsigned char c = *from; if (c & 0xc0) @@ -304,6 +304,8 @@ namespace std ++from; continue; } + + if (max == 0) break; unsigned char tmp; if (state.value & 0x8) |