]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR libstdc++/66145 allow catching iostream errors as cxx11 ios::failure
authorJonathan Wakely <jwakely@redhat.com>
Wed, 8 Aug 2018 15:40:11 +0000 (16:40 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 8 Aug 2018 15:40:11 +0000 (16:40 +0100)
Define a new exception type derived from the gcc4-compatible ios::failure
which also aggregates an object of the ios::failure[abi:cxx11] type.
Make __throw_ios_failure throw this new type for iostream errors
that raise exceptions. Provide custom type info for the new type so that
it can be caught by handlers for ios::failure[abi:cxx11] type
as well as handlers for the gcc4-compatible ios::failure and its bases.

Backport from mainline
2018-04-10  Jonathan Wakely  <jwakely@redhat.com>

PR libstdc++/85222
* src/c++11/cxx11-ios_failure.cc (__construct_ios_failure)
(__destroy_ios_failure, is_ios_failure_handler): New functions.
* src/c++11/ios.cc (__throw_ios_failure): Remove definition.
(_GLIBCXX_USE_CXX11_ABI): Don't define here.
* src/c++98/Makefile.am [ENABLE_DUAL_ABI]: Add special rules for
ios_failure.cc to rewrite type info for __ios_failure.
* src/c++98/Makefile.in: Regenerate.
* src/c++98/ios_failure.cc [_GLIBCXX_USE_DUAL_ABI]
(__iosfailure, __iosfailure_type_info): New types.
(__throw_ios_failure): Define here.
* testsuite/27_io/ios_base/failure/dual_abi.cc: New.
* testsuite/27_io/basic_ios/copyfmt/char/1.cc: Revert changes to
add -D_GLIBCXX_USE_CXX11_ABI=0 to dg-options.
* testsuite/27_io/basic_ios/exceptions/char/1.cc: Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/char/
exceptions_failbit.cc: Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/
exceptions_failbit.cc: Likewise.
* testsuite/27_io/basic_istream/extractors_other/char/
exceptions_null.cc: Likewise.
* testsuite/27_io/basic_istream/extractors_other/wchar_t/
exceptions_null.cc: Likewise.
* testsuite/27_io/basic_istream/sentry/char/12297.cc: Likewise.
* testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_other/char/
exceptions_null.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_other/wchar_t/
exceptions_null.cc: Likewise.
* testsuite/27_io/ios_base/storage/2.cc: Likewise.

From-SVN: r263414

18 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/src/c++11/cxx11-ios_failure.cc
libstdc++-v3/src/c++11/ios.cc
libstdc++-v3/src/c++98/Makefile.am
libstdc++-v3/src/c++98/Makefile.in
libstdc++-v3/src/c++98/ios_failure.cc
libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc
libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc
libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc
libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc
libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc
libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc
libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc
libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc
libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc

index 7813800172a7ff2256c5e74507f5091e61974c8d..ca31df19ec07dabfb2ab5a9a19ab023260417134 100644 (file)
@@ -1,3 +1,40 @@
+2018-08-08  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/66145
+       Backport from mainline
+       2018-04-10  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/85222
+       * src/c++11/cxx11-ios_failure.cc (__construct_ios_failure)
+       (__destroy_ios_failure, is_ios_failure_handler): New functions.
+       * src/c++11/ios.cc (__throw_ios_failure): Remove definition.
+       (_GLIBCXX_USE_CXX11_ABI): Don't define here.
+       * src/c++98/Makefile.am [ENABLE_DUAL_ABI]: Add special rules for
+       ios_failure.cc to rewrite type info for __ios_failure.
+       * src/c++98/Makefile.in: Regenerate.
+       * src/c++98/ios_failure.cc [_GLIBCXX_USE_DUAL_ABI]
+       (__iosfailure, __iosfailure_type_info): New types.
+       (__throw_ios_failure): Define here.
+       * testsuite/27_io/ios_base/failure/dual_abi.cc: New.
+       * testsuite/27_io/basic_ios/copyfmt/char/1.cc: Revert changes to
+       add -D_GLIBCXX_USE_CXX11_ABI=0 to dg-options.
+       * testsuite/27_io/basic_ios/exceptions/char/1.cc: Likewise.
+       * testsuite/27_io/basic_istream/extractors_arithmetic/char/
+       exceptions_failbit.cc: Likewise.
+       * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/
+       exceptions_failbit.cc: Likewise.
+       * testsuite/27_io/basic_istream/extractors_other/char/
+       exceptions_null.cc: Likewise.
+       * testsuite/27_io/basic_istream/extractors_other/wchar_t/
+       exceptions_null.cc: Likewise.
+       * testsuite/27_io/basic_istream/sentry/char/12297.cc: Likewise.
+       * testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc: Likewise.
+       * testsuite/27_io/basic_ostream/inserters_other/char/
+       exceptions_null.cc: Likewise.
+       * testsuite/27_io/basic_ostream/inserters_other/wchar_t/
+       exceptions_null.cc: Likewise.
+       * testsuite/27_io/ios_base/storage/2.cc: Likewise.
+
 2018-07-05  François Dumont  <fdumont@gcc.gnu.org>
 
        Backport from mainline
index b102e24eb28f3e14e6e02104d293a238a106c300..9c819423cd012bb7708f7ecc1f9191e6c584eefd 100644 (file)
@@ -28,6 +28,8 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <ios>
+#include <typeinfo>
+#include <cxxabi.h>
 
 #if ! _GLIBCXX_USE_DUAL_ABI
 # error This file should not be compiled for this configuration.
@@ -91,5 +93,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
+  // __throw_ios_failure() is defined in src/c++98/ios_failure.cc
+
+#if __cpp_rtti
+  // If RTTI is enabled the exception type thrown will use these functions to
+  // construct/destroy a ios::failure[abi:cxx11] object in a buffer,
+  // and to catch that object via a handler of the [abi:cxx11] type.
+  void
+  __construct_ios_failure(void* buf, const char* msg)
+  { ::new(buf) ios_base::failure(msg); }
+
+  void
+  __destroy_ios_failure(void* buf)
+  { static_cast<ios_base::failure*>(buf)->~failure(); }
+
+  bool
+  __is_ios_failure_handler(const __cxxabiv1::__class_type_info* type)
+  { return *type == typeid(ios::failure); }
+
+  // static assertions to ensure ios::failure fits in a buffer
+  // with the same size and alignment as system_error:
+  static_assert(sizeof(ios::failure) <= sizeof(system_error), "");
+  static_assert(__alignof(ios::failure) <= __alignof(system_error), "");
+#endif // __cpp_rtti
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
index f65f7e35a503a8272ead202b9b6c0191890f633a..e0c14ecf8e171070ad2a80a3e1e5d9039e1db8d8 100644 (file)
 // ISO C++ 14882: 27.4  Iostreams base classes
 //
 
-// Determines the version of ios_base::failure thrown by __throw_ios_failure.
-// If !_GLIBCXX_USE_DUAL_ABI this will get undefined automatically.
-#define _GLIBCXX_USE_CXX11_ABI 0
-
 #include <ios>
 #include <limits>
-#include <bits/functexcept.h>
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  void
-  __throw_ios_failure(const char* __s __attribute__((unused)))
-  { _GLIBCXX_THROW_OR_ABORT(ios_base::failure(_(__s))); }
-
   // Definitions for static const members of ios_base.
   const ios_base::fmtflags ios_base::boolalpha;
   const ios_base::fmtflags ios_base::dec;
index 21a1343daebdd2e7d31625447e82755aa0b8ac4e..0b95c247a8083c2f5546be99d1b8fdc9af72d5e1 100644 (file)
@@ -215,6 +215,26 @@ parallel_settings.lo: parallel_settings.cc
 parallel_settings.o: parallel_settings.cc
        $(CXXCOMPILE) $(PARALLEL_FLAGS) -c $<
 
+if ENABLE_DUAL_ABI
+# Rewrite the type info for __iosfailure.
+rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt12__iosfailure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt22__iosfailure_type_info/'
+
+ios_failure-lt.s: ios_failure.cc
+       $(LTCXXCOMPILE) -S $< -o tmp-ios_failure-lt.s
+       -test -f tmp-ios_failure-lt.o && mv -f tmp-ios_failure-lt.o tmp-ios_failure-lt.s
+       $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
+       -rm -f tmp-$@
+ios_failure.s: ios_failure.cc
+       $(CXXCOMPILE) -S $< -o tmp-$@
+       $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
+       -rm -f tmp-$@
+
+ios_failure.lo: ios_failure-lt.s
+       $(LTCXXCOMPILE) -g0 -c $< -o $@
+ios_failure.o: ios_failure.s
+       $(CXXCOMPILE) -g0 -c $<
+endif
+
 # AM_CXXFLAGS needs to be in each subdirectory so that it can be
 # modified in a per-library or per-sub-library way.  Need to manually
 # set this option because CONFIG_CXXFLAGS has to be after
index 3c3bbbd17f72f3e07ecb44fb6adaf4221cba8059..ab7464fddeacb4f227ffd0a20434a194d3b2460d 100644 (file)
@@ -437,6 +437,9 @@ GLIBCXX_INCLUDE_DIR = $(glibcxx_builddir)/include
 # Use special rules for parallel mode compilation.
 PARALLEL_FLAGS = -D_GLIBCXX_PARALLEL 
 
+# Rewrite the type info for __iosfailure.
+@ENABLE_DUAL_ABI_TRUE@rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt12__iosfailure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt22__iosfailure_type_info/'
+
 # AM_CXXFLAGS needs to be in each subdirectory so that it can be
 # modified in a per-library or per-sub-library way.  Need to manually
 # set this option because CONFIG_CXXFLAGS has to be after
@@ -826,6 +829,21 @@ parallel_settings.lo: parallel_settings.cc
 parallel_settings.o: parallel_settings.cc
        $(CXXCOMPILE) $(PARALLEL_FLAGS) -c $<
 
+@ENABLE_DUAL_ABI_TRUE@ios_failure-lt.s: ios_failure.cc
+@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -S $< -o tmp-ios_failure-lt.s
+@ENABLE_DUAL_ABI_TRUE@ -test -f tmp-ios_failure-lt.o && mv -f tmp-ios_failure-lt.o tmp-ios_failure-lt.s
+@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
+@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@
+@ENABLE_DUAL_ABI_TRUE@ios_failure.s: ios_failure.cc
+@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) -S $< -o tmp-$@
+@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
+@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@
+
+@ENABLE_DUAL_ABI_TRUE@ios_failure.lo: ios_failure-lt.s
+@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -c $< -o $@
+@ENABLE_DUAL_ABI_TRUE@ios_failure.o: ios_failure.s
+@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) -c $<
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index ac90525279c117421f1ea809b00bbd4305ab462e..b7bd66348fce2948699d59fe99aa43bdf12f9302 100644 (file)
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#include <cxxabi.h>
+#include <typeinfo>
+#endif
+
+#ifdef _GLIBCXX_USE_NLS
+# include <libintl.h>
+# define _(msgid)   gettext (msgid)
+#else
+# define _(msgid)   (msgid)
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -43,5 +55,80 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
 
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+  // These functions are defined in src/c++11/cxx11-ios_failure.cc
+  extern void __construct_ios_failure(void*, const char*);
+  extern void __destroy_ios_failure(void*);
+  extern bool __is_ios_failure_handler(const __cxxabiv1::__class_type_info*);
+
+  // The type thrown to report errors during stream buffer operations.
+  // In addition to the gcc4-compatible ios::failure base class it also has a
+  // member of the ios::failure[abi:cxx11] type (in an opaque buffer).
+  struct __iosfailure : std::ios::failure
+  {
+    __iosfailure(const char* s) : failure(s)
+    { __construct_ios_failure(buf, failure::what()); }
+
+    ~__iosfailure() throw()
+    { __destroy_ios_failure(buf); }
+
+    // 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;
+    };
+
+    // Use __system_error as a proxy for the ios::failure[abi:cxx11]
+    // (which can't be declared here because _GLIBCXX_USE_CXX11_ABI == 0).
+    // There are assertions in src/c++11/cxx11-ios_failure.cc to ensure the
+    // size and alignment assumptions are valid.
+    __attribute__((aligned(__alignof(__system_error))))
+      unsigned char buf[sizeof(__system_error)];
+  };
+
+  // Custom type info for __ios_failure.
+  class __iosfailure_type_info : __cxxabiv1::__si_class_type_info
+  {
+    ~__iosfailure_type_info();
+
+    bool
+    __do_upcast (const __class_type_info *dst_type,
+                void **obj_ptr) const;
+  };
+
+  __iosfailure_type_info::~__iosfailure_type_info() { }
+
+  // This function gets called to see if an exception of type
+  // __ios_failure can be upcast to the type in a catch handler.
+  bool
+  __iosfailure_type_info::__do_upcast(const __class_type_info *dst_type,
+                                     void **obj_ptr) const
+  {
+    // If the handler is for the ios::failure[abi:cxx11] type then
+    // catch the object stored in __ios_failure::buf instead of
+    // the __ios_failure exception object itself.
+    if (__is_ios_failure_handler(dst_type))
+      {
+       *obj_ptr = static_cast<__iosfailure*>(*obj_ptr)->buf;
+       return true;
+      }
+    // Otherwise proceeed as normal to see if the handler matches.
+    return __class_type_info::__do_upcast(dst_type, obj_ptr);
+  }
+#else // _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+  using __iosfailure = ios::failure;
+#endif
+
+  void
+  __throw_ios_failure(const char* __s __attribute__((unused)))
+  { _GLIBCXX_THROW_OR_ABORT(__iosfailure(_(__s))); }
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
index df4cf43598a8ff5f43d43e8c5918ab726b0e163f..9e23f568fbee7cbe1c8592d2f03c5cfa309d5aa9 100644 (file)
@@ -17,9 +17,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 // 27.4.4.2 basic_ios member functions
 
 // NB: Don't include any other headers in this file.
index c2357fcff35205b965e9474133952911ae3a3d53..e55b86cbaf74d314976596f57cc7adfa198523de 100644 (file)
@@ -17,9 +17,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 // 27.4.4.2 basic_ios member functions
 
 // NB: Don't include any other headers in this file.
index 91e2fea9d4293844798de603c680e2edce1e7b1e..1ea715e0655b49d811640af696139f647d5ee99e 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <sstream>
 #include <testsuite_hooks.h>
 
@@ -30,7 +27,7 @@ void test_failbit()
 
   istringstream stream("jaylib - champion sound");
   stream.exceptions(ios_base::failbit);
-  
+
   try
     {
       T i;
index 088b2ca846dcaa1170f028d6cdc9e72eaabc1793..4c5f402a006fab6dfbf8eef25d23457ae1756f86 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <sstream>
 #include <testsuite_hooks.h>
 
@@ -30,7 +27,7 @@ void test_failbit()
 
   wistringstream stream(L"jaylib - champion sound");
   stream.exceptions(ios_base::failbit);
-  
+
   try
     {
       T i;
index f6842fbea7eb08b81e755d63ec6bbe612a9663f2..7fdc9598ab6e91bfe5df29ec2c59db1d0d8ce7a0 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <istream>
 #include <ostream>
 #include <streambuf>
index 7ca929febfa6154bf75a5fd3baba4be437fbfc94..fffed0d987d8bbc31cd346516f0642246b9534d9 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <istream>
 #include <ostream>
 #include <streambuf>
index 6ffbc06ae00043a643cf7bcd2b973563ccf37575..cefb7df54833dec875d00baf19f86110521c6cdb 100644 (file)
@@ -18,9 +18,6 @@
 
 // 27.6.1.1.2 class basic_istream::sentry
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <sstream>
 #include <testsuite_hooks.h>
 
@@ -29,7 +26,7 @@ int main()
   using namespace std;
   istringstream stream;
   stream.exceptions(ios_base::eofbit);
-  
+
   try
     {
       istream::sentry sentry(stream, false);
index ccc519e0b28d21cc975c2c366ad95297a8acd376..29a4b94f1eb773e7d144860630b148350316f599 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 // 27.6.1.1.2 class basic_istream::sentry
 
 #include <sstream>
@@ -28,7 +25,7 @@ int main()
   using namespace std;
   wistringstream stream;
   stream.exceptions(ios_base::eofbit);
-  
+
   try
     {
       wistream::sentry sentry(stream, false);
index 6eac572969fa43c6721fd2e571870e3cd54534ea..a0213b1d6bde043b8ab53ff41f7c456e4b40f943 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <istream>
 #include <ostream>
 #include <streambuf>
@@ -41,7 +38,7 @@ void test3()
 
   ostringstream stream;
   stream.exceptions(ios_base::badbit);
-       
+
   try
     {
       stream << static_cast<streambuf*>(0);
index 1de18ede7f3aa3862a19e7ae1654fccfee9a266a..095b1ae782454047b39864874e429af60e87bdac 100644 (file)
@@ -15,9 +15,6 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <istream>
 #include <ostream>
 #include <streambuf>
@@ -41,7 +38,7 @@ void test3()
 
   wostringstream stream;
   stream.exceptions(ios_base::badbit);
-       
+
   try
     {
       stream << static_cast<wstreambuf*>(0);
diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc
new file mode 100644 (file)
index 0000000..4d19f40
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright (C) 2018 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 "-D_GLIBCXX_USE_CXX11_ABI=1" }
+// { dg-do run }
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  using std::ios;
+  bool caught_ios_failure = false;
+  bool rethrown = false;
+  bool caught_exception = false;
+  try {
+    std::ifstream f;
+    f.exceptions(ios::failbit | ios::badbit | ios::eofbit);
+    try {
+      f.get();
+    }
+    catch (const ios::failure&) // catch as new ABI type
+    {
+      caught_ios_failure = true;
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI == 1
+      rethrown = true;
+      throw; // re-throw, to catch as old ABI type
+#endif
+    }
+  }
+  catch (const std::exception& e)
+  {
+    caught_exception = true;
+  }
+
+  VERIFY( caught_ios_failure );
+  if (rethrown)
+    VERIFY( caught_exception );
+}
+
+void
+test02()
+{
+  using std::ios;
+  const std::exception* p = nullptr;
+  bool caught_ios_failure = false;
+  bool caught_exception = false;
+  try {
+    std::ifstream f;
+    f.exceptions(ios::failbit | ios::badbit | ios::eofbit);
+    try {
+      f.get();
+    }
+    catch (const std::exception& e1)
+    {
+      caught_exception = true;
+      p = &e1;
+      throw;
+    }
+  }
+  catch (const ios::failure& e2)
+  {
+    caught_ios_failure = true;
+#if _GLIBCXX_USE_DUAL_ABI
+    // If the Dual ABI is active the library throws the old type,
+    // so e1 was an object of that old type and so &e1 != &e2.
+    VERIFY( p != &e2 );
+#else
+    // Otherwise there's only one type of ios::failure, so &e1 == &e2.
+    VERIFY( p == &e2 );
+#endif
+  }
+
+  VERIFY( caught_exception );
+  VERIFY( caught_ios_failure );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
index 8b33732f098ae485f1ccafefdc924ca0605f664c..549e8ee1cb71566569a7c61818fe5c5bf3e2c37f 100644 (file)
@@ -28,9 +28,6 @@
 // Radar 6467884: 10.X systems are not robust when paging space is exceeded
 // { dg-skip-if "" { *-*-darwin* && lp64 } { "*" } { "" } } 
 
-// The library still throws the original definition of std::ios::failure
-// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" }
-
 #include <sstream>
 #include <iostream>
 #include <limits>
@@ -52,8 +49,8 @@ void test02()
   // pword
   ios.pword(1) = v;
   VERIFY( ios.pword(1) == v );
-  
-  try 
+
+  try
     {
       v = ios.pword(max);
     }