]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR libstdc++/53984 handle exceptions in basic_istream::sentry
authorJonathan Wakely <jwakely@redhat.com>
Mon, 4 Sep 2017 17:09:01 +0000 (18:09 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 4 Sep 2017 17:09:01 +0000 (18:09 +0100)
Backport from mainline
2017-07-25  Jonathan Wakely  <jwakely@redhat.com>

PR libstdc++/53984
* include/bits/basic_ios.h (basic_ios::_M_setstate): Adjust comment.
* include/bits/istream.tcc (basic_istream::sentry): Handle exceptions
during construction.
* include/std/istream: Adjust comments for formatted input functions
and unformatted input functions.
* testsuite/27_io/basic_fstream/53984.cc: New.
* testsuite/27_io/basic_istream/sentry/char/53984.cc: New.

From-SVN: r251679

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_ios.h
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/std/istream
libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/53984.cc [new file with mode: 0644]

index 465f996e967bbe6bf625b012f573e999d72d9889..ade7cb179e13f9a53f720bd6916f89f668ca5f63 100644 (file)
@@ -1,5 +1,17 @@
 2017-09-04  Jonathan Wakely  <jwakely@redhat.com>
 
+       Backport from mainline
+       2017-07-25  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/53984
+       * include/bits/basic_ios.h (basic_ios::_M_setstate): Adjust comment.
+       * include/bits/istream.tcc (basic_istream::sentry): Handle exceptions
+       during construction.
+       * include/std/istream: Adjust comments for formatted input functions
+       and unformatted input functions.
+       * testsuite/27_io/basic_fstream/53984.cc: New.
+       * testsuite/27_io/basic_istream/sentry/char/53984.cc: New.
+
        Backport from mainline
        2017-06-08  Jonathan Wakely  <jwakely@redhat.com>
 
index 8bea1761fc8e30a48e64dc85466700f9e287dec3..0e4509903d4cac0c3cde491b989419f6ee24e0a8 100644 (file)
@@ -157,8 +157,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       setstate(iostate __state)
       { this->clear(this->rdstate() | __state); }
 
-      // Flip the internal state on for the proper state bits, then re
-      // throws the propagated exception if bit also set in
+      // Flip the internal state on for the proper state bits, then
+      // rethrows the propagated exception if bit also set in
       // exceptions().
       void
       _M_setstate(iostate __state)
index e8cbb261b8a901625fbba3aa8cabbf93d10a1a02..904d40d0cd6f60e061250bcb1242b5b6a3d02d54 100644 (file)
@@ -48,28 +48,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       ios_base::iostate __err = ios_base::goodbit;
       if (__in.good())
-       {
-         if (__in.tie())
-           __in.tie()->flush();
-         if (!__noskip && bool(__in.flags() & ios_base::skipws))
-           {
-             const __int_type __eof = traits_type::eof();
-             __streambuf_type* __sb = __in.rdbuf();
-             __int_type __c = __sb->sgetc();
-
-             const __ctype_type& __ct = __check_facet(__in._M_ctype);
-             while (!traits_type::eq_int_type(__c, __eof)
-                    && __ct.is(ctype_base::space, 
-                               traits_type::to_char_type(__c)))
-               __c = __sb->snextc();
+       __try
+         {
+           if (__in.tie())
+             __in.tie()->flush();
+           if (!__noskip && bool(__in.flags() & ios_base::skipws))
+             {
+               const __int_type __eof = traits_type::eof();
+               __streambuf_type* __sb = __in.rdbuf();
+               __int_type __c = __sb->sgetc();
+
+               const __ctype_type& __ct = __check_facet(__in._M_ctype);
+               while (!traits_type::eq_int_type(__c, __eof)
+                      && __ct.is(ctype_base::space,
+                                 traits_type::to_char_type(__c)))
+                 __c = __sb->snextc();
 
-             // _GLIBCXX_RESOLVE_LIB_DEFECTS
-             // 195. Should basic_istream::sentry's constructor ever
-             // set eofbit?
-             if (traits_type::eq_int_type(__c, __eof))
-               __err |= ios_base::eofbit;
-           }
-       }
+               // _GLIBCXX_RESOLVE_LIB_DEFECTS
+               // 195. Should basic_istream::sentry's constructor ever
+               // set eofbit?
+               if (traits_type::eq_int_type(__c, __eof))
+                 __err |= ios_base::eofbit;
+             }
+         }
+       __catch(__cxxabiv1::__forced_unwind&)
+         {
+           __in._M_setstate(ios_base::badbit);
+           __throw_exception_again;
+         }
+       __catch(...)
+         { __in._M_setstate(ios_base::badbit); }
 
       if (__in.good() && __err == ios_base::goodbit)
        _M_ok = true;
index 74c0d81e0a37f9641e40b1546f726592264ae2dc..deb50d31ea832d0f56c59deb220594b9db6fd003 100644 (file)
@@ -150,9 +150,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  whatever data is appropriate for the type of the argument.
        *
        *  If an exception is thrown during extraction, ios_base::badbit
-       *  will be turned on in the stream's error state without causing an
-       *  ios_base::failure to be thrown.  The original exception will then
-       *  be rethrown.
+       *  will be turned on in the stream's error state (without causing an
+       *  ios_base::failure to be thrown) and the original exception will
+       *  be rethrown if badbit is set in the exceptions mask.
       */
 
       //@{
@@ -286,9 +286,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  by gcount().
        *
        *  If an exception is thrown during extraction, ios_base::badbit
-       *  will be turned on in the stream's error state without causing an
-       *  ios_base::failure to be thrown.  The original exception will then
-       *  be rethrown.
+       *  will be turned on in the stream's error state (without causing an
+       *  ios_base::failure to be thrown) and the original exception will
+       *  be rethrown if badbit is set in the exceptions mask.
       */
 
       /**
diff --git a/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc b/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc
new file mode 100644 (file)
index 0000000..a319aff
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2017 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 "" }
+
+// PR libstdc++/53984
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  std::ifstream in(".");
+  if (in)
+  {
+    char c;
+    if (in.get(c))
+    {
+      // Reading a directory doesn't produce an error on this target
+      // so the formatted input functions below wouldn't fail anyway
+      // (see PR libstdc++/81808).
+      return;
+    }
+    int x;
+    in.clear();
+    // Formatted input function should set badbit, but not throw:
+    in >> x;
+    VERIFY( in.bad() );
+
+    in.clear();
+    in.exceptions(std::ios::badbit);
+    try
+    {
+      // Formatted input function should set badbit, and throw:
+      in >> x;
+      VERIFY( false );
+    }
+    catch (const std::exception&)
+    {
+      VERIFY( in.bad() );
+    }
+  }
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/53984.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/53984.cc
new file mode 100644 (file)
index 0000000..9c08c72
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2017 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/>.
+
+#include <streambuf>
+#include <istream>
+#include <testsuite_hooks.h>
+
+struct SB : std::streambuf
+{
+  virtual int_type underflow() { throw 1; }
+};
+
+void
+test01()
+{
+  SB sb;
+  std::istream is(&sb);
+  int i;
+  is >> i;
+  VERIFY( is.bad() );
+}
+
+int
+main()
+{
+  test01();
+}