Define C++11 version of std::ios_base::failure.
authorJonathan Wakely <jwakely@redhat.com>
Fri, 14 Nov 2014 12:17:57 +0000 (12:17 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 14 Nov 2014 12:17:57 +0000 (12:17 +0000)
* config/abi/pre/gnu.ver: Add new exports.
* include/bits/ios_base.h (ios_base::failure): New definition using
abi_tag.
(io_errc, make_error_code, make_error_category, iostream_category):
Define.
* include/std/system_error (system_error): Add char* constructors.
* src/c++11/Makefile.am: Add new file.
* src/c++11/Makefile.in: Regenerate.
* src/c++11/cxx11-ios_failure.cc: New file.
* src/c++98/ios_failure.cc: Compile old definition without abi_tag.
* testsuite/27_io/ios_base/failure/cxx11.cc: New.
* testsuite/27_io/ios_base/failure/what-1.cc: Allow string returned by
ios_base::failure::what() to contain additional data.
* testsuite/27_io/ios_base/failure/what-2.cc: Likewise..
* testsuite/27_io/ios_base/failure/what-3.cc: Likewise..
* testsuite/27_io/ios_base/failure/what-big.cc: Likewise..

From-SVN: r217559

13 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/bits/ios_base.h
libstdc++-v3/include/std/system_error
libstdc++-v3/src/c++11/Makefile.am
libstdc++-v3/src/c++11/Makefile.in
libstdc++-v3/src/c++11/cxx11-ios_failure.cc [new file with mode: 0644]
libstdc++-v3/src/c++98/ios_failure.cc
libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc
libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc
libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc
libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc

index 65408784c893f27950de8f5f6b8ade56d01dc1d3..18e214fc94b97e637a63188365de4d8ed7e851df 100644 (file)
@@ -1,3 +1,22 @@
+2014-11-14  Jonathan Wakely  <jwakely@redhat.com>
+
+       * config/abi/pre/gnu.ver: Add new exports.
+       * include/bits/ios_base.h (ios_base::failure): New definition using
+       abi_tag.
+       (io_errc, make_error_code, make_error_category, iostream_category):
+       Define.
+       * include/std/system_error (system_error): Add char* constructors.
+       * src/c++11/Makefile.am: Add new file.
+       * src/c++11/Makefile.in: Regenerate.
+       * src/c++11/cxx11-ios_failure.cc: New file.
+       * src/c++98/ios_failure.cc: Compile old definition without abi_tag.
+       * testsuite/27_io/ios_base/failure/cxx11.cc: New.
+       * testsuite/27_io/ios_base/failure/what-1.cc: Allow string returned by
+       ios_base::failure::what() to contain additional data.
+       * testsuite/27_io/ios_base/failure/what-2.cc: Likewise..
+       * testsuite/27_io/ios_base/failure/what-3.cc: Likewise..
+       * testsuite/27_io/ios_base/failure/what-big.cc: Likewise..
+
 2014-11-13  Daniel Kruegler  <daniel.kruegler@gmail.com>
 
        * include/bits/regex.h: Support embedded zeros in sub_match
index bd44bcc3ba63db98d26445c5ce4f7c1063d7b8ed..78f3e77a1dee9045a22485590ed164f95c15996e 100644 (file)
@@ -1473,6 +1473,18 @@ GLIBCXX_3.4.21 {
     # std::basic_ios::operator bool() const
     _ZNKSt9basic_iosI[cw]St11char_traitsI[cw]EEcvbEv;
 
+    # C++11 version of std::ios_base::failure
+    _ZNKSt8ios_base7failureB5cxx114whatEv;
+    _ZNSt8ios_base7failureB5cxx11C[12]ERKSs;
+    _ZNSt8ios_base7failureB5cxx11C[12]EPKcRKSt10error_code;
+    _ZNSt8ios_base7failureB5cxx11C[12]ERKSsB5cxx11;
+    _ZNSt8ios_base7failureB5cxx11C[12]ERKSsB5cxx11RKSt10error_code;
+    _ZNSt8ios_base7failureB5cxx11D[012]Ev;
+    _ZTINSt8ios_base7failureB5cxx11E;
+    _ZTSNSt8ios_base7failureB5cxx11E;
+    _ZTVNSt8ios_base7failureB5cxx11E;
+    _ZSt17iostream_categoryv;
+
     # std::ctype_base::blank
     _ZNSt10ctype_base5blankE;
 
index 5e33b812fe3b7595b8632fac11bed43837fc9e12..8e600598fe2a4de52df96ea3d27fa53d8a2ad6de 100644 (file)
 #include <bits/localefwd.h>
 #include <bits/locale_classes.h>
 
+#if __cplusplus < 201103L
+# include <stdexcept>
+#else
+# include <system_error>
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -186,6 +192,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _S_ios_seekdir_end = 1L << 16 
     };
 
+#if __cplusplus >= 201103L
+  /// I/O error code
+  enum class io_errc { stream = 1 };
+
+  template <> struct is_error_code_enum<io_errc> : public true_type { };
+
+  const error_category& iostream_category() noexcept;
+
+  inline error_code
+  make_error_code(io_errc e) noexcept
+  { return error_code(static_cast<int>(e), iostream_category()); }
+
+  inline error_condition
+  make_error_condition(io_errc e) noexcept
+  { return error_condition(static_cast<int>(e), iostream_category()); }
+#endif
+
   // 27.4.2  Class ios_base
   /**
    *  @brief  The base of the I/O class hierarchy.
@@ -198,6 +221,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   class ios_base
   {
+#if _GLIBCXX_USE_CXX11_ABI
+#if __cplusplus < 201103L
+    // Type that is layout-compatible with std::system_error
+    struct system_error : std::runtime_error
+    {
+      // Type that is layout-compatible with std::error_code
+      struct error_code
+      {
+       error_code() { }
+      private:
+       int             _M_value;
+       const void*     _M_cat;
+      } _M_code;
+    };
+#endif
+#endif
   public:
 
     /** 
@@ -206,6 +245,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
      *
      *  27.4.2.1.1  Class ios_base::failure
      */
+#if _GLIBCXX_USE_CXX11_ABI
+    class _GLIBCXX_ABI_TAG_CXX11 failure : public system_error
+    {
+    public:
+      explicit
+      failure(const string& __str);
+
+#if __cplusplus >= 201103L
+      explicit
+      failure(const string&, const error_code&);
+
+      explicit
+      failure(const char*, const error_code& = io_errc::stream);
+#endif
+
+      virtual
+      ~failure() throw();
+
+      virtual const char*
+      what() const throw();
+    };
+#else
     class failure : public exception
     {
     public:
@@ -225,6 +286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private:
       string _M_msg;
     };
+#endif
 
     // 27.4.2.1.2  Type ios_base::fmtflags
     /**
index 4ec83d77c4e1c7f090206b12d0e874b47062c0c2..ed17f554bca3744d12864616bd9767e0308efd2d 100644 (file)
@@ -321,16 +321,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     system_error(error_code __ec, const string& __what)
     : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { }
 
-    /*
-     * TODO: Add const char* ctors to all exceptions.
-     *
-     * system_error(error_code __ec, const char* __what)
-     * : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
-     *
-     * system_error(int __v, const error_category& __ecat, const char* __what)
-     * : runtime_error(__what + (": " + __ec.message())),
-     *   _M_code(error_code(__v, __ecat)) { }
-     */
+    system_error(error_code __ec, const char* __what)
+    : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
+
+    system_error(int __v, const error_category& __ecat, const char* __what)
+    : system_error(error_code(__v, __ecat), __what) { }
 
     system_error(int __v, const error_category& __ecat)
     : runtime_error(error_code(__v, __ecat).message()),
index c8507cec8dfe89d61cbb8550c2f496864bd45cd5..71306db4b006a2ff840bea4864e0aafbe35b52ac 100644 (file)
@@ -39,6 +39,13 @@ ctype_configure_char.cc: ${glibcxx_srcdir}/$(OS_INC_SRCDIR)/ctype_configure_char
 ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
        $(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
+if ENABLE_CXX11_ABI
+cxx11_abi_sources = \
+       cxx11-ios_failure.cc
+else
+cxx11_abi_sources =
+endif
+
 sources = \
        chrono.cc \
        condition_variable.cc \
@@ -59,6 +66,7 @@ sources = \
        snprintf_lite.cc \
        system_error.cc \
        thread.cc \
+       ${cxx11_abi_sources} \
        ${host_sources}
 
 if ENABLE_EXTERN_TEMPLATE
index fd3e7801d85845383aa04dab3b991513e6ba8c8e..dd9e110f76885123d65bb5132681a1e4f6b8dcb9 100644 (file)
@@ -67,19 +67,20 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
-am__objects_1 = ctype_configure_char.lo ctype_members.lo
-am__objects_2 = chrono.lo condition_variable.lo ctype.lo debug.lo \
+@ENABLE_CXX11_ABI_TRUE@am__objects_1 = cxx11-ios_failure.lo
+am__objects_2 = ctype_configure_char.lo ctype_members.lo
+am__objects_3 = chrono.lo condition_variable.lo ctype.lo debug.lo \
        functexcept.lo functional.lo future.lo hash_c++0x.lo \
        hashtable_c++0x.lo ios.lo limits.lo mutex.lo placeholders.lo \
        random.lo regex.lo shared_ptr.lo snprintf_lite.lo \
-       system_error.lo thread.lo $(am__objects_1)
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = ext11-inst.lo \
+       system_error.lo thread.lo $(am__objects_1) $(am__objects_2)
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = ext11-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  fstream-inst.lo ios-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  iostream-inst.lo istream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  ostream-inst.lo sstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  streambuf-inst.lo string-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  wstring-inst.lo
-am_libc__11convenience_la_OBJECTS = $(am__objects_2) $(am__objects_3)
+am_libc__11convenience_la_OBJECTS = $(am__objects_3) $(am__objects_4)
 libc__11convenience_la_OBJECTS = $(am_libc__11convenience_la_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp =
@@ -322,6 +323,10 @@ host_sources = \
        ctype_configure_char.cc \
        ctype_members.cc
 
+@ENABLE_CXX11_ABI_FALSE@cxx11_abi_sources = 
+@ENABLE_CXX11_ABI_TRUE@cxx11_abi_sources = \
+@ENABLE_CXX11_ABI_TRUE@        cxx11-ios_failure.cc
+
 sources = \
        chrono.cc \
        condition_variable.cc \
@@ -342,6 +347,7 @@ sources = \
        snprintf_lite.cc \
        system_error.cc \
        thread.cc \
+       ${cxx11_abi_sources} \
        ${host_sources}
 
 # XTEMPLATE_FLAGS =
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
new file mode 100644 (file)
index 0000000..143d70e
--- /dev/null
@@ -0,0 +1,89 @@
+// Iostreams base classes -*- C++ -*-
+
+// Copyright (C) 2014 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// ISO C++ 14882:2011: 27.5.3.1.1  Class ios_base::failure
+//
+
+#include <ios>
+
+namespace
+{
+  struct io_error_category : std::error_category
+  {
+    virtual const char*
+    name() const noexcept
+    { return "iostream"; }
+
+    virtual std::string message(int __ec) const
+    {
+      std::string __msg;
+      switch (std::io_errc(__ec))
+      {
+      case std::io_errc::stream:
+          __msg = "iostream error";
+          break;
+      default:
+          __msg = "Unknown error";
+          break;
+      }
+      return __msg;
+    }
+  };
+
+  const io_error_category&
+  __io_category_instance() noexcept
+  {
+    static const io_error_category __ec{};
+    return __ec;
+  }
+
+} // namespace
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  const error_category&
+  iostream_category() noexcept
+  { return __io_category_instance(); }
+
+  ios_base::failure::failure(const string& __str)
+  : system_error(io_errc::stream, __str) { }
+
+  ios_base::failure::failure(const string& __str, const error_code& __ec)
+  : system_error(__ec, __str) { }
+
+  ios_base::failure::failure(const char* __str, const error_code& __ec)
+  : system_error(__ec, __str) { }
+
+  ios_base::failure::~failure()
+  { }
+
+  const char*
+  ios_base::failure::what() const throw()
+  { return runtime_error::what(); }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
index 9d32e51c957a56e9a41170c0e8f1ad594b3e19d1..0f4517800ce7024f0095515666d7fb6f14412317 100644 (file)
 // <http://www.gnu.org/licenses/>.
 
 //
-// ISO C++ 14882: 27.4.2.1.1  Class ios_base::failure
+// ISO C++ 14882:1998: 27.4.2.1.1  Class ios_base::failure
 //
 
+#define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
 namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc
new file mode 100644 (file)
index 0000000..a3276e1
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2014 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-options "-std=gnu++11" }
+
+#include <ios>
+#include <testsuite_hooks.h>
+
+using test_type = std::ios_base::failure;
+
+static_assert( std::is_base_of<std::system_error, test_type>::value, "base" );
+
+void
+test01()
+{
+  test_type e("io error");
+  VERIFY(std::string(e.what()).find("io error") != std::string::npos);
+  e = test_type("", make_error_code(std::io_errc::stream));
+}
+
+struct E : test_type
+{
+  E(const char* s) : test_type(s, make_error_code(std::io_errc::stream)) { }
+};
+
+void
+test02()
+{
+  E e("io error");
+  VERIFY(std::string(e.what()).find("io error") != std::string::npos);
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
index 07be43bfddb8158c655afec97d5fa010d11c131e..a50c798b14c9247b5eb51dc2a4d8cb125441dee6 100644 (file)
@@ -37,8 +37,13 @@ void test01()
   // 2
   std::ios_base::failure obj2(s);
 
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( std::strstr(obj1.what(), s.data()) != NULL );
+  VERIFY( std::strstr(obj2.what(), s.data()) != NULL );
+#else
   VERIFY( std::strcmp(obj1.what(), s.data()) == 0 );
   VERIFY( std::strcmp(obj2.what(), s.data()) == 0 );
+#endif
 }
 
 void test02()
@@ -47,7 +52,11 @@ void test02()
   std::string s("lack of sunlight error");
   std::range_error x(s);
   
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( std::strstr(x.what(), s.data()) != NULL );
+#else
   VERIFY( std::strcmp(x.what(), s.data()) == 0 );
+#endif
 }
 
 int main(void)
index 334c8e1fcad6fe419e9df90c80d1c0b604430e72..e16ef7c64d95c1e900356ae8843ca5148fcc6479 100644 (file)
@@ -37,7 +37,13 @@ void test03()
   try
     { throw fuzzy_logic(); }
   catch(const fuzzy_logic& obj)
-    { VERIFY( std::strcmp("whoa", obj.what()) == 0 ); }
+    {
+#if _GLIBCXX_USE_CXX11_ABI
+      VERIFY( std::strstr(obj.what(), "whoa") != NULL );
+#else
+      VERIFY( std::strcmp("whoa", obj.what()) == 0 );
+#endif
+    }
   catch(...)
     { VERIFY( false ); }
 }
index b9af939df82c2325de95e82beb4dabdfe371e9b4..abbbcca7826f03a277f1d163646a8c35f99d3466 100644 (file)
@@ -52,7 +52,11 @@ void test04()
     obj1 = obj2;
   }
   allocate_on_stack();
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( std::strstr(obj1.what(), strlit1) != NULL );
+#else
   VERIFY( std::strcmp(strlit1, obj1.what()) == 0 ); 
+#endif
 
   // block 02
   {
@@ -61,7 +65,11 @@ void test04()
     obj1 = obj3;
   }
   allocate_on_stack();     
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( std::strstr(obj1.what(), strlit2) != NULL );
+#else
   VERIFY( std::strcmp(strlit2, obj1.what()) == 0 ); 
+#endif
 }
 
 int main(void)
index a2bd37c972c1a625938afa9b8238cb96cb78a98c..99ee17d68393d6d23dc969f28c1816ecaf662334 100644 (file)
@@ -30,7 +30,11 @@ void test01()
   bool test __attribute__((unused)) = true;
   const std::string xxx(10000, 'x');
   test_type t(xxx);
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( std::strstr(t.what(), xxx.c_str()) != NULL );
+#else
   VERIFY( std::strcmp(t.what(), xxx.c_str()) == 0 );
+#endif
 }
 
 int main(void)