public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-1817] libstdc++: Implement LWG 581 for std:ostream::flush() Date: Fri, 25 Jun 2021 19:51:09 +0000 (GMT) [thread overview] Message-ID: <20210625195109.2A552385E00E@sourceware.org> (raw) https://gcc.gnu.org/g:f8c5b542f6cb6a947600e34420565ac67486ea14 commit r12-1817-gf8c5b542f6cb6a947600e34420565ac67486ea14 Author: Jonathan Wakely <jwakely@redhat.com> Date: Fri Jun 25 18:31:23 2021 +0100 libstdc++: Implement LWG 581 for std:ostream::flush() LWG 581 changed ostream::flush() to an unformatted output function for C++11, but it was never implemented in libstdc++. libstdc++-v3/ChangeLog: * doc/xml/manual/intro.xml: Document LWG 581 change. * doc/html/manual/bugs.html: Regenerate. * include/bits/basic_ios.tcc: Whitespace. * include/bits/ostream.tcc (basic_ostream::flush()): Construct sentry. * testsuite/27_io/basic_ostream/flush/char/2.cc: Check additional cases. * testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc: Likewise. * testsuite/27_io/basic_ostream/flush/wchar_t/2.cc: Likewise. * testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc: Likewise. Diff: --- libstdc++-v3/doc/html/manual/bugs.html | 3 ++ libstdc++-v3/doc/xml/manual/intro.xml | 6 +++ libstdc++-v3/include/bits/basic_ios.tcc | 2 +- libstdc++-v3/include/bits/ostream.tcc | 35 ++++++++++------ .../testsuite/27_io/basic_ostream/flush/char/2.cc | 48 +++++++++++++++++----- .../flush/char/exceptions_badbit_throw.cc | 16 ++++---- .../27_io/basic_ostream/flush/wchar_t/2.cc | 48 +++++++++++++++++----- .../flush/wchar_t/exceptions_badbit_throw.cc | 16 ++++---- 8 files changed, 126 insertions(+), 48 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index 7e0837322e5..7b49e4ab87c 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -303,6 +303,9 @@ </p></dd><dt><a id="manual.bugs.dr550"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550" target="_top">550</a>: <span class="emphasis"><em>What should the return type of pow(float,int) be?</em></span> </span></dt><dd><p>In C++11 mode, remove the pow(float,int), etc., signatures. + </p></dd><dt><a id="manual.bugs.dr581"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#581" target="_top">581</a>: + <span class="emphasis"><em><code class="code">flush()</code> not unformatted function</em></span> + </span></dt><dd><p>Change it to be a unformatted output function (i.e. construct a sentry and catch exceptions). </p></dd><dt><a id="manual.bugs.dr586"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#586" target="_top">586</a>: <span class="emphasis"><em>string inserter not a formatted function</em></span> </span></dt><dd><p>Change it to be a formatted output function (i.e. catch exceptions). diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 3e7843f58c1..45762caa711 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -743,6 +743,12 @@ requirements of the license of GCC. <listitem><para>In C++11 mode, remove the pow(float,int), etc., signatures. </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr581"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#581">581</link>: + <emphasis><code>flush()</code> not unformatted function</emphasis> + </term> + <listitem><para>Change it to be a unformatted output function (i.e. construct a sentry and catch exceptions). + </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr586"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#586">586</link>: <emphasis>string inserter not a formatted function</emphasis> </term> diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc index 6285f734031..664a9f22759 100644 --- a/libstdc++-v3/include/bits/basic_ios.tcc +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -43,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (this->rdbuf()) _M_streambuf_state = __state; else - _M_streambuf_state = __state | badbit; + _M_streambuf_state = __state | badbit; if (this->exceptions() & this->rdstate()) __throw_ios_failure(__N("basic_ios::clear")); } diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index 20585f447ac..d3220e8034b 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -213,21 +213,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() is *not* an unformatted output function. - ios_base::iostate __err = ios_base::goodbit; - __try - { - if (this->rdbuf() && this->rdbuf()->pubsync() == -1) - __err |= ios_base::badbit; - } - __catch(__cxxabiv1::__forced_unwind&) + // 581. flush() not unformatted function + // basic_ostream::flush() *is* an unformatted output function. + if (__streambuf_type* __buf = this->rdbuf()) { - this->_M_setstate(ios_base::badbit); - __throw_exception_again; + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + __try + { + if (this->rdbuf()->pubsync() == -1) + __err |= ios_base::badbit; + } + __catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } } - __catch(...) - { this->_M_setstate(ios_base::badbit); } - if (__err) - this->setstate(__err); return *this; } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc index 0b33e60bd08..96969debca7 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc @@ -22,42 +22,70 @@ // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() does not behave as an unformatted output function. +// But wait ... +// 581. flush() not unformatted function +// So now basic_ostream::flush() *is* an unformatted output function. #include <ostream> #include <testsuite_hooks.h> #include <testsuite_io.h> +void +test01() +{ + std::ostream os(0); + VERIFY( os.bad() ); + + // Nothing should happen if os.rdbuf() is null. No sentry is constructed. + os.flush(); + VERIFY( os.rdstate() == std::ios_base::badbit ); // no failbit + + os.exceptions(std::ios_base::failbit); + os.flush(); +} + void test02() { __gnu_test::sync_streambuf buf; std::ostream os(&buf); - + __gnu_test::sync_streambuf buf_tie; std::ostream os_tie(&buf_tie); - // No sentry should be constructed so os.tie()->flush() should not be - // called. + // A sentry should be constructed so os.tie()->flush() should be called. os.tie(&os_tie); - + os.flush(); VERIFY( os.good() ); VERIFY( buf.sync_called() ); - VERIFY( !buf_tie.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} - // os.rdbuf()->pubsync() should be called even if !os.good(). +void +test03() +{ + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + os.tie(&os_tie); + + // os.rdbuf()->pubsync() should not be called if !os.good(). os.setstate(std::ios_base::eofbit); os.flush(); - VERIFY( os.rdstate() == std::ios_base::eofbit ); - VERIFY( buf.sync_called() ); + VERIFY( os.rdstate() & std::ios_base::eofbit ); + VERIFY( !buf.sync_called() ); VERIFY( !buf_tie.sync_called() ); } int main() { + test01(); test02(); - return 0; + test03(); } - diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc index bba5fb0baa2..115b00478a7 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc @@ -28,21 +28,23 @@ void test01() { __gnu_test::fail_streambuf bib; ostream stream(&bib); + + stream.flush(); // should catch exception and set badbit + VERIFY( stream.rdstate() == ios_base::badbit ); + + stream.clear(); stream.exceptions(ios_base::badbit); try { - stream.flush(); + stream.flush(); // should catch exception and set badbit and rethrow VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.rdstate() == ios_base::badbit ); } - catch (...) + catch (...) { VERIFY( false ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc index 3711fdedcd5..4403fd3cdf5 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc @@ -20,42 +20,70 @@ // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() does not behave as an unformatted output function. +// But wait ... +// 581. flush() not unformatted function +// So now basic_ostream::flush() *is* an unformatted output function. #include <ostream> #include <testsuite_hooks.h> #include <testsuite_io.h> +void +test01() +{ + std::wostream os(0); + VERIFY( os.bad() ); + + // Nothing should happen if os.rdbuf() is null. No sentry is constructed. + os.flush(); + VERIFY( os.rdstate() == std::ios_base::badbit ); // no failbit + + os.exceptions(std::ios_base::failbit); + os.flush(); +} + void test02() { __gnu_test::sync_wstreambuf buf; std::wostream os(&buf); - + __gnu_test::sync_wstreambuf buf_tie; std::wostream os_tie(&buf_tie); - // No sentry should be constructed so os.tie()->flush() should not be - // called. + // A sentry should be constructed so os.tie()->flush() should be called. os.tie(&os_tie); - + os.flush(); VERIFY( os.good() ); VERIFY( buf.sync_called() ); - VERIFY( !buf_tie.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} - // os.rdbuf()->pubsync() should be called even if !os.good(). +void +test03() +{ + __gnu_test::sync_wstreambuf buf; + std::wostream os(&buf); + + __gnu_test::sync_wstreambuf buf_tie; + std::wostream os_tie(&buf_tie); + + os.tie(&os_tie); + + // os.rdbuf()->pubsync() should not be called if !os.good(). os.setstate(std::ios_base::eofbit); os.flush(); - VERIFY( os.rdstate() == std::ios_base::eofbit ); - VERIFY( buf.sync_called() ); + VERIFY( os.rdstate() & std::ios_base::eofbit ); + VERIFY( !buf.sync_called() ); VERIFY( !buf_tie.sync_called() ); } int main() { + test01(); test02(); - return 0; + test03(); } - diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc index 86440e14f6f..d88f385a6c3 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc @@ -28,21 +28,23 @@ void test01() { __gnu_test::fail_wstreambuf bib; wostream stream(&bib); + + stream.flush(); // should catch exception and set badbit + VERIFY( stream.rdstate() == ios_base::badbit ); + + stream.clear(); stream.exceptions(ios_base::badbit); try { - stream.flush(); + stream.flush(); // should catch exception and set badbit and rethrow VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.rdstate() == ios_base::badbit ); } - catch (...) + catch (...) { VERIFY( false ); }
reply other threads:[~2021-06-25 19:51 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210625195109.2A552385E00E@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).