diff options
author | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-04-28 17:15:03 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-04-28 17:15:03 +0000 |
commit | 2aacd7357ad4eded006166c5431b23cf998a381f (patch) | |
tree | 4a1cc92b2ffd9b17f90a5ca3efc07f400bdc081a | |
parent | ff4cb2e75b5f471edc5c1fc46d4bdebac58b6c7a (diff) | |
download | gcc-2aacd7357ad4eded006166c5431b23cf998a381f.zip gcc-2aacd7357ad4eded006166c5431b23cf998a381f.tar.gz gcc-2aacd7357ad4eded006166c5431b23cf998a381f.tar.bz2 |
[multiple changes]
2003-04-28 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/9523
* include/bits/ios_base.h (Init::_S_ios_create,
Init::_S_ios_destroy): Remove declarations.
(Init::_S_create_buffers,
Init::_S_destroy_buffers): Declare
* src/ios.cc (Init::_S_ios_create): Remove
(Init::_S_create_buffers): Create buffers and add to streams.
(Init::_S_ios_destroy): Rename to...
(Init::_S_destroy_buffers): this.
(Init::Init): Only construct streams once.
(Init::~Init): Flush streams, don't destroy them.
(ios_base::sync_with_stdio): Don't destroy streams, only buffers.
* testsuite/27_io/ios_base/sync_with_stdio/9523.cc: New test.
* testsuite/27_io/objects/char/5.cc: New test.
* testsuite/27_io/objects/char/5268.cc: Avoid undefined behavior.
* testsuite/27_io/objects/char/6.cc: New test.
* testsuite/27_io/objects/char/7.cc: New test.
2003-04-28 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/27_io/objects/char/8.cc: New test.
From-SVN: r66177
-rw-r--r-- | libstdc++-v3/ChangeLog | 24 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/ios_base.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/src/ios.cc | 78 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc | 51 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/objects/char/5.cc | 85 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/objects/char/5268.cc | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/objects/char/6.cc | 50 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/objects/char/7.cc | 75 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/objects/char/8.cc | 51 |
9 files changed, 394 insertions, 25 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 597c68f..fa1adb1 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,27 @@ +2003-04-28 Petur Runolfsson <peturr02@ru.is> + + PR libstdc++/9523 + * include/bits/ios_base.h (Init::_S_ios_create, + Init::_S_ios_destroy): Remove declarations. + (Init::_S_create_buffers, + Init::_S_destroy_buffers): Declare + * src/ios.cc (Init::_S_ios_create): Remove + (Init::_S_create_buffers): Create buffers and add to streams. + (Init::_S_ios_destroy): Rename to... + (Init::_S_destroy_buffers): this. + (Init::Init): Only construct streams once. + (Init::~Init): Flush streams, don't destroy them. + (ios_base::sync_with_stdio): Don't destroy streams, only buffers. + * testsuite/27_io/ios_base/sync_with_stdio/9523.cc: New test. + * testsuite/27_io/objects/char/5.cc: New test. + * testsuite/27_io/objects/char/5268.cc: Avoid undefined behavior. + * testsuite/27_io/objects/char/6.cc: New test. + * testsuite/27_io/objects/char/7.cc: New test. + +2003-04-28 Benjamin Kosnik <bkoz@redhat.com> + + * testsuite/27_io/objects/char/8.cc: New test. + 2003-04-28 Benjamin Kosnik <bkoz@redhat.com> * testsuite/22_locale/codecvt/unicode/char.cc: Remove bom usage. diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 0adea49..618c903 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -453,10 +453,10 @@ namespace std ~Init(); static void - _S_ios_create(bool __sync); + _S_create_buffers(bool __sync); static void - _S_ios_destroy(); + _S_destroy_buffers(); // NB: Allows debugger applications use of the standard streams // from operator new. _S_ios_base_init must be incremented in diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 284c09e..7ce3339 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -154,39 +154,34 @@ namespace std { return _M_name; } void - ios_base::Init::_S_ios_create(bool __sync) + ios_base::Init::_S_create_buffers(bool __sync) { size_t __out_size = __sync ? 0 : static_cast<size_t>(BUFSIZ); size_t __in_size = __sync ? 1 : static_cast<size_t>(BUFSIZ); - // NB: The file globals.cc creates the four standard files - // with NULL buffers. At this point, we swap out the dummy NULL - // [io]stream objects and buffers with the real deal. + // Create stream buffers for the standard streams and use those + // buffers without destroying and recreating the streams. new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size); new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size); new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size); - new (&cout) ostream(&buf_cout); - new (&cin) istream(&buf_cin); - new (&cerr) ostream(&buf_cerr); - new (&clog) ostream(&buf_cerr); - cin.tie(&cout); - cerr.flags(ios_base::unitbuf); + cout.rdbuf(&buf_cout); + cin.rdbuf(&buf_cin); + cerr.rdbuf(&buf_cerr); + clog.rdbuf(&buf_cerr); #ifdef _GLIBCPP_USE_WCHAR_T new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size); new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size); new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size); - new (&wcout) wostream(&buf_wcout); - new (&wcin) wistream(&buf_wcin); - new (&wcerr) wostream(&buf_wcerr); - new (&wclog) wostream(&buf_wcerr); - wcin.tie(&wcout); - wcerr.flags(ios_base::unitbuf); + wcout.rdbuf(&buf_wcout); + wcin.rdbuf(&buf_wcin); + wcerr.rdbuf(&buf_wcerr); + wclog.rdbuf(&buf_wcerr); #endif } void - ios_base::Init::_S_ios_destroy() + ios_base::Init::_S_destroy_buffers() { // Explicitly call dtors to free any memory that is dynamically // allocated by filebuf ctor or member functions, but don't @@ -208,15 +203,52 @@ namespace std { // Standard streams default to synced with "C" operations. ios_base::Init::_S_synced_with_stdio = true; - _S_ios_create(ios_base::Init::_S_synced_with_stdio); + + // The standard streams are constructed once only and never destroyed. + // The stream buffers are set in _S_create_buffers below. + new (&cout) ostream(NULL); + new (&cin) istream(NULL); + new (&cerr) ostream(NULL); + new (&clog) ostream(NULL); + cin.tie(&cout); + cerr.flags(ios_base::unitbuf); + +#ifdef _GLIBCPP_USE_WCHAR_T + new (&wcout) wostream(NULL); + new (&wcin) wistream(NULL); + new (&wcerr) wostream(NULL); + new (&wclog) wostream(NULL); + wcin.tie(&wcout); + wcerr.flags(ios_base::unitbuf); +#endif + + _S_create_buffers(ios_base::Init::_S_synced_with_stdio); + _S_ios_base_init = 1; } ++_S_ios_base_init; } ios_base::Init::~Init() { - if (--_S_ios_base_init == 0) - _S_ios_destroy(); + if (--_S_ios_base_init == 1) + { + // Catch any exceptions thrown by basic_ostream::flush() + try + { + // Flush standard output streams as required by 27.4.2.1.6 + cout.flush(); + cerr.flush(); + clog.flush(); + +#ifdef _GLIBCPP_USE_WCHAR_T + wcout.flush(); + wcerr.flush(); + wclog.flush(); +#endif + } + catch (...) + { } + } } // 27.4.2.5 ios_base storage functions @@ -355,9 +387,9 @@ namespace std // currently synchronized. if (!__sync && __ret) { - ios_base::Init::_S_synced_with_stdio = false; - ios_base::Init::_S_ios_destroy(); - ios_base::Init::_S_ios_create(ios_base::Init::_S_synced_with_stdio); + ios_base::Init::_S_synced_with_stdio = __sync; + ios_base::Init::_S_destroy_buffers(); + ios_base::Init::_S_create_buffers(__sync); } return __ret; } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc new file mode 100644 index 0000000..f0b3f83 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc @@ -0,0 +1,51 @@ +// 2003-04-26 Petur Runolfsson <peturr02@ru.is> + +// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.4.2.4 ios_base static members + +#include <testsuite_hooks.h> +#include <iostream> + +// libstdc++/9523 +void test01() +{ + using namespace std; + + int index = ios_base::xalloc(); + + cin.iword(index) = 5; + cout.iword(index) = 6; + cerr.iword(index) = 7; + clog.iword(index) = 8; + + ios_base::sync_with_stdio(false); + + VERIFY( cin.iword(index) == 5 ); + VERIFY( cout.iword(index) == 6 ); + VERIFY( cerr.iword(index) == 7 ); + VERIFY( clog.iword(index) == 8 ); +} + +int main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/27_io/objects/char/5.cc b/libstdc++-v3/testsuite/27_io/objects/char/5.cc new file mode 100644 index 0000000..aa15e93 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/5.cc @@ -0,0 +1,85 @@ +// 2003-04-26 Petur Runolfsson <peturr02@ru.is> + +// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.3 Standard iostream objects + +// Check that standard streams can be used from constructors and +// destructors of static objects, provided that an instance of +// ios_base::Init has been constructed. + +void init_standard_streams(); +int use_standard_streams(); + +struct Strange +{ + int i; + + Strange() + { + init_standard_streams(); + i = use_standard_streams(); + } + + ~Strange() + { + use_standard_streams(); + init_standard_streams(); + } +}; + +static Strange static_ob; + +#include <testsuite_hooks.h> +#include <iostream> + +void init_standard_streams() +{ + std::ios_base::Init init; +} + +int use_standard_streams() +{ + std::cout << "Hello, world!" << std::endl; + std::cerr << "World, hello!" << std::endl; + + int ret = std::ios_base::xalloc(); + std::cin.iword(ret) = ret + 1; + std::cout.iword(ret) = ret + 2; + std::cerr.iword(ret) = ret + 3; + std::clog.iword(ret) = ret + 4; + return ret; +} + +void test05() +{ + bool test = true; + int i = static_ob.i; + + VERIFY( std::cin.iword(i) == i + 1 ); + VERIFY( std::cout.iword(i) == i + 2 ); + VERIFY( std::cerr.iword(i) == i + 3 ); + VERIFY( std::clog.iword(i) == i + 4 ); +} + +int main() +{ + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/objects/char/5268.cc b/libstdc++-v3/testsuite/27_io/objects/char/5268.cc index 36f9019..5364172 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/5268.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/5268.cc @@ -36,6 +36,7 @@ void test04() std::stringbuf b1; std::cout.rdbuf( &b1 ); std::cout << "hello\n"; + std::cout.rdbuf(NULL); } int main() diff --git a/libstdc++-v3/testsuite/27_io/objects/char/6.cc b/libstdc++-v3/testsuite/27_io/objects/char/6.cc new file mode 100644 index 0000000..c7ecbc6 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/6.cc @@ -0,0 +1,50 @@ +// 2003-04-26 Petur Runolfsson <peturr02@ru.is> + +// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.3 Standard iostream objects + +// ios_base::Init::~Init() calls cout.flush(), which may call +// cout.setstate(badbit), which may throw an exception. Check that +// the exception doesn't escape from the destructor. + +#include <iostream> +#include <streambuf> + +class Badbuf : public std::streambuf +{ +protected: + virtual int sync() + { + return -1; + } +}; + +void test06() +{ + std::ios_base::Init init; + std::cout.rdbuf(new Badbuf); + std::cout.exceptions(std::ios_base::badbit); +} + +int main() +{ + test06(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/objects/char/7.cc b/libstdc++-v3/testsuite/27_io/objects/char/7.cc new file mode 100644 index 0000000..c6f353e --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/7.cc @@ -0,0 +1,75 @@ +// 2003-04-26 Petur Runolfsson <peturr02@ru.is> + +// 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 +// 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.3 Standard iostream objects + +#include <fstream> +#include <iostream> +#include <unistd.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <testsuite_hooks.h> + +// Check that cout.flush() is called when last ios_base::Init is destroyed. +void test07() +{ + using namespace std; + bool test = true; + + const char* name = "tmp_fifo4"; + + signal(SIGPIPE, SIG_IGN); + + unlink(name); + mkfifo(name, S_IRWXU); + + int child = fork(); + VERIFY( child != -1 ); + + if (child == 0) + { + filebuf fbout; + sleep(1); + fbout.open(name, ios_base::out); + cout.rdbuf(&fbout); + fbout.sputc('a'); + sleep(2); + // NB: fbout is *not* destroyed here! + exit(0); + } + + filebuf fbin; + fbin.open(name, ios_base::in); + sleep(2); + filebuf::int_type c = fbin.sbumpc(); + VERIFY( c != filebuf::traits_type::eof() ); + VERIFY( c == filebuf::traits_type::to_int_type('a') ); + + fbin.close(); +} + +int +main() +{ + test07(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/objects/char/8.cc b/libstdc++-v3/testsuite/27_io/objects/char/8.cc new file mode 100644 index 0000000..28a06a1 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/8.cc @@ -0,0 +1,51 @@ +// 2003-04-28 Benjamin Kosnik <bkoz@redhat.com> + +// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + + // 27.3 - Standard iostream objects p 2 + +#include <iostream> +#include <testsuite_hooks.h> + +void test02() +{ + bool test = true; + + // 27.3 - Standard iostream objects p 2 + // The objects are not destroyed during program execution. + void* p1 = &std::cout; + void* p2 = &std::cin; + void* p3 = &std::cerr; + void* p4 = &std::clog; + std::ios_base::sync_with_stdio(false); + void* p1s = &std::cout; + void* p2s = &std::cin; + void* p3s = &std::cerr; + void* p4s = &std::clog; + VERIFY( p1 == p1s ); + VERIFY( p2 == p2s ); + VERIFY( p3 == p3s ); + VERIFY( p4 == p4s ); +} + +int main(void) +{ + test02(); + return 0; +} |