PR libstdc++/85222 allow catching iostream errors as gcc4-compatible ios::failure
Define a new exception type derived from std::ios::failure[abi:cxx11] which also aggregates an object of the gcc4-compatible ios::failure 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 the gcc4-compatible ios::failure type as well as handlers for ios::failure[abi:cxx11] and its bases. PR libstdc++/85222 * src/c++11/Makefile.am [ENABLE_DUAL_ABI]: Add special rules for cxx11-ios_failure.cc to rewrite type info for __ios_failure. * src/c++11/Makefile.in: Regenerate. * src/c++11/cxx11-ios_failure.cc (__ios_failure, __iosfail_type_info): New types. [_GLIBCXX_USE_DUAL_ABI] (__throw_ios_failure): Define here. * src/c++11/ios.cc (__throw_ios_failure): Remove definition. * src/c++98/ios_failure.cc (__construct_ios_failure) (__destroy_ios_failure, is_ios_failure_handler): New functions. [!_GLIBCXX_USE_DUAL_ABI] (__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 handler types, to always catch std::ios_base::failure. * 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: r259281
This commit is contained in:
parent
7e6b73b1c0
commit
5f30251862
@ -1,3 +1,36 @@
|
||||
2018-04-10 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/85222
|
||||
* src/c++11/Makefile.am [ENABLE_DUAL_ABI]: Add special rules for
|
||||
cxx11-ios_failure.cc to rewrite type info for __ios_failure.
|
||||
* src/c++11/Makefile.in: Regenerate.
|
||||
* src/c++11/cxx11-ios_failure.cc (__ios_failure, __iosfail_type_info):
|
||||
New types.
|
||||
[_GLIBCXX_USE_DUAL_ABI] (__throw_ios_failure): Define here.
|
||||
* src/c++11/ios.cc (__throw_ios_failure): Remove definition.
|
||||
* src/c++98/ios_failure.cc (__construct_ios_failure)
|
||||
(__destroy_ios_failure, is_ios_failure_handler): New functions.
|
||||
[!_GLIBCXX_USE_DUAL_ABI] (__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
|
||||
handler types, to always catch std::ios_base::failure.
|
||||
* 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-04-05 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/std/variant (_VARIANT_RELATION_FUNCTION_TEMPLATE): Qualify
|
||||
|
@ -126,6 +126,29 @@ hashtable_c++0x.lo: hashtable_c++0x.cc
|
||||
hashtable_c++0x.o: hashtable_c++0x.cc
|
||||
$(CXXCOMPILE) -fimplicit-templates -c $<
|
||||
|
||||
if ENABLE_DUAL_ABI
|
||||
# Rewrite the type info for __dual_abi_ios_failure.
|
||||
rewrite_ios_failure_typeinfo = sed -e '/^_ZTISt13__ios_failure:$$/{' \
|
||||
-e 'n' \
|
||||
-e 's/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/' \
|
||||
-e '}'
|
||||
|
||||
cxx11-ios_failure-lt.s: cxx11-ios_failure.cc
|
||||
$(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s
|
||||
-test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s
|
||||
$(rewrite_ios_failure_typeinfo) tmp-$@ > $@
|
||||
-rm -f tmp-$@
|
||||
cxx11-ios_failure.s: cxx11-ios_failure.cc
|
||||
$(CXXCOMPILE) -S $< -o tmp-$@
|
||||
$(rewrite_ios_failure_typeinfo) tmp-$@ > $@
|
||||
-rm -f tmp-$@
|
||||
|
||||
cxx11-ios_failure.lo: cxx11-ios_failure-lt.s
|
||||
$(LTCXXCOMPILE) -c $< -o $@
|
||||
cxx11-ios_failure.o: cxx11-ios_failure.s
|
||||
$(CXXCOMPILE) -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
|
||||
|
@ -434,6 +434,13 @@ sources = \
|
||||
|
||||
libc__11convenience_la_SOURCES = $(sources) $(inst_sources)
|
||||
|
||||
# Rewrite the type info for __dual_abi_ios_failure.
|
||||
@ENABLE_DUAL_ABI_TRUE@rewrite_ios_failure_typeinfo = sed -e '/^_ZTISt13__ios_failure:$$/{' \
|
||||
@ENABLE_DUAL_ABI_TRUE@ -e 'n' \
|
||||
@ENABLE_DUAL_ABI_TRUE@ -e 's/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/' \
|
||||
@ENABLE_DUAL_ABI_TRUE@ -e '}'
|
||||
|
||||
|
||||
# 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
|
||||
@ -749,6 +756,21 @@ hashtable_c++0x.lo: hashtable_c++0x.cc
|
||||
hashtable_c++0x.o: hashtable_c++0x.cc
|
||||
$(CXXCOMPILE) -fimplicit-templates -c $<
|
||||
|
||||
@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure-lt.s: cxx11-ios_failure.cc
|
||||
@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s
|
||||
@ENABLE_DUAL_ABI_TRUE@ -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s
|
||||
@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
|
||||
@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@
|
||||
@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.s: cxx11-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@cxx11-ios_failure.lo: cxx11-ios_failure-lt.s
|
||||
@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -c $< -o $@
|
||||
@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.o: cxx11-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:
|
||||
|
@ -28,6 +28,15 @@
|
||||
|
||||
#define _GLIBCXX_USE_CXX11_ABI 1
|
||||
#include <ios>
|
||||
#include <bits/functexcept.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
#ifdef _GLIBCXX_USE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
#else
|
||||
# define _(msgid) (msgid)
|
||||
#endif
|
||||
|
||||
#if ! _GLIBCXX_USE_DUAL_ABI
|
||||
# error This file should not be compiled for this configuration.
|
||||
@ -91,5 +100,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
ios_base::failure::what() const throw()
|
||||
{ return runtime_error::what(); }
|
||||
|
||||
#if __cpp_rtti
|
||||
// These functions are defined in src/c++98/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 ios::failure[abi:cxx11] base class it also has a
|
||||
// member of the gcc4-compatible ios::failure type (in an opaque buffer).
|
||||
struct __ios_failure : std::ios::failure
|
||||
{
|
||||
__ios_failure(const char* s) : failure(s)
|
||||
{ __construct_ios_failure(buf, runtime_error::what()); }
|
||||
|
||||
~__ios_failure()
|
||||
{ __destroy_ios_failure(buf); }
|
||||
|
||||
// Use std::runtime_error as a proxy for the gcc4-compatible ios::failure
|
||||
// (which can't be declared here because _GLIBCXX_USE_CXX11_ABI == 1).
|
||||
// There are assertions in src/c++98/ios_failure.cc to ensure the size
|
||||
// and alignment assumptions are valid.
|
||||
alignas(runtime_error) unsigned char buf[sizeof(runtime_error)];
|
||||
};
|
||||
|
||||
// Custom type info for __ios_failure.
|
||||
class __iosfail_type_info : __cxxabiv1::__si_class_type_info
|
||||
{
|
||||
~__iosfail_type_info();
|
||||
|
||||
bool
|
||||
__do_upcast (const __class_type_info *dst_type,
|
||||
void **obj_ptr) const override;
|
||||
};
|
||||
|
||||
__iosfail_type_info::~__iosfail_type_info() = default;
|
||||
|
||||
// This function gets called to see if an exception of type
|
||||
// __ios_failure can be upcast to the type in a catch handler.
|
||||
bool
|
||||
__iosfail_type_info::__do_upcast(const __class_type_info *dst_type,
|
||||
void **obj_ptr) const
|
||||
{
|
||||
// If the handler is for the gcc4-compatible ios::failure 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<__ios_failure*>(*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 // ! __cpp_rtti
|
||||
using __ios_failure = ios::failure;
|
||||
#endif
|
||||
|
||||
void
|
||||
__throw_ios_failure(const char* __s __attribute__((unused)))
|
||||
{ _GLIBCXX_THROW_OR_ABORT(__ios_failure(_(__s))); }
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
@ -32,23 +32,11 @@
|
||||
|
||||
#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;
|
||||
|
@ -29,6 +29,18 @@
|
||||
#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,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
ios_base::failure::what() const throw()
|
||||
{ return _M_msg.c_str(); }
|
||||
|
||||
#if _GLIBCXX_USE_DUAL_ABI
|
||||
// When the dual ABI is enabled __throw_ios_failure() is defined in
|
||||
// src/c++11/ios_failure.cc
|
||||
#if __cpp_rtti
|
||||
// If RTTI is enabled the exception type thrown will use these functions to
|
||||
// construct/destroy a gcc4-compatible ios::failure object in a buffer,
|
||||
// and to catch that object via a handler of the gcc4-compatible 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); }
|
||||
|
||||
namespace {
|
||||
// C++98-style static assertions to ensure ios::failure fits in a buffer
|
||||
// with the same size and alignment as runtime_error:
|
||||
typedef char S[1 / (sizeof(ios::failure) <= sizeof(runtime_error))];
|
||||
typedef char A[1 / (__alignof(ios::failure) <= __alignof(runtime_error))];
|
||||
}
|
||||
#endif // __cpp_rtti
|
||||
|
||||
#else // ! _GLIBCXX_USE_DUAL_ABI
|
||||
|
||||
void
|
||||
__throw_ios_failure(const char* __s __attribute__((unused)))
|
||||
{ _GLIBCXX_THROW_OR_ABORT(ios::failure(_(__s))); }
|
||||
|
||||
#endif
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
@ -46,13 +46,6 @@ void test02()
|
||||
}
|
||||
|
||||
{
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
std::ios ios_01(0);
|
||||
std::ios ios_02(0);
|
||||
ios_01.clear(std::ios_base::eofbit);
|
||||
@ -62,7 +55,7 @@ void test02()
|
||||
ios_01.copyfmt(ios_02);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch(exception_type&) {
|
||||
catch(std::ios_base::failure&) {
|
||||
VERIFY( true );
|
||||
}
|
||||
catch(...) {
|
||||
|
@ -50,20 +50,13 @@ void test01()
|
||||
}
|
||||
|
||||
{
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
std::ios ios_01(0);
|
||||
ios_01.clear(std::ios_base::eofbit);
|
||||
try {
|
||||
ios_01.exceptions(std::ios_base::eofbit);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch(exception_type&) {
|
||||
catch(std::ios_base::failure&) {
|
||||
iostate02 = ios_01.exceptions();
|
||||
VERIFY( static_cast<bool>(iostate02 & std::ios_base::eofbit) );
|
||||
}
|
||||
|
@ -27,20 +27,13 @@ void test_failbit()
|
||||
istringstream stream("jaylib - champion sound");
|
||||
stream.exceptions(ios_base::failbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
T i;
|
||||
stream >> i;
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (const exception_type&)
|
||||
catch (const std::ios_base::failure&)
|
||||
{
|
||||
// stream should set failbit and throw ios_base::failure.
|
||||
VERIFY( stream.fail() );
|
||||
|
@ -27,20 +27,13 @@ void test_failbit()
|
||||
wistringstream stream(L"jaylib - champion sound");
|
||||
stream.exceptions(ios_base::failbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
T i;
|
||||
stream >> i;
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (const exception_type&)
|
||||
catch (const std::ios_base::failure&)
|
||||
{
|
||||
// stream should set failbit and throw ios_base::failure.
|
||||
VERIFY( stream.fail() );
|
||||
|
@ -35,19 +35,12 @@ void test4()
|
||||
istringstream stream;
|
||||
stream.exceptions(ios_base::failbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
stream >> static_cast<streambuf*>(0);
|
||||
VERIFY(false);
|
||||
}
|
||||
catch (exception_type&)
|
||||
catch (std::ios_base::failure&)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -35,19 +35,12 @@ void test4()
|
||||
wistringstream stream;
|
||||
stream.exceptions(ios_base::failbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
stream >> static_cast<wstreambuf*>(0);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (exception_type&)
|
||||
catch (std::ios_base::failure&)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,19 +26,12 @@ int main()
|
||||
istringstream stream;
|
||||
stream.exceptions(ios_base::eofbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
istream::sentry sentry(stream, false);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (exception_type&)
|
||||
catch (std::ios_base::failure&)
|
||||
{
|
||||
VERIFY( stream.rdstate() == (ios_base::eofbit | ios_base::failbit) );
|
||||
}
|
||||
|
@ -26,19 +26,12 @@ int main()
|
||||
wistringstream stream;
|
||||
stream.exceptions(ios_base::eofbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
wistream::sentry sentry(stream, false);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (exception_type&)
|
||||
catch (std::ios_base::failure&)
|
||||
{
|
||||
VERIFY( stream.rdstate() == (ios_base::eofbit | ios_base::failbit) );
|
||||
}
|
||||
|
@ -37,19 +37,12 @@ void test3()
|
||||
ostringstream stream;
|
||||
stream.exceptions(ios_base::badbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
stream << static_cast<streambuf*>(0);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (exception_type&)
|
||||
catch (std::ios_base::failure&)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -37,19 +37,12 @@ void test3()
|
||||
wostringstream stream;
|
||||
stream.exceptions(ios_base::badbit);
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
stream << static_cast<wstreambuf*>(0);
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (exception_type&)
|
||||
catch (std::ios_base::failure&)
|
||||
{
|
||||
}
|
||||
|
||||
|
99
libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc
Normal file
99
libstdc++-v3/testsuite/27_io/ios_base/failure/dual_abi.cc
Normal file
@ -0,0 +1,99 @@
|
||||
// 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=0" }
|
||||
// { dg-do run { target c++11 } }
|
||||
|
||||
#include <fstream>
|
||||
#include <system_error>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
using std::ios;
|
||||
bool caught_ios_failure = false;
|
||||
bool rethrown = false;
|
||||
bool caught_system_error = false;
|
||||
try {
|
||||
std::ifstream f;
|
||||
f.exceptions(ios::failbit | ios::badbit | ios::eofbit);
|
||||
try {
|
||||
f.get();
|
||||
}
|
||||
catch (const ios::failure&) // catch as old ABI type
|
||||
{
|
||||
caught_ios_failure = true;
|
||||
#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI == 1
|
||||
rethrown = true;
|
||||
throw; // re-throw, to catch as new ABI type
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
{
|
||||
caught_system_error = true;
|
||||
}
|
||||
|
||||
VERIFY( caught_ios_failure );
|
||||
if (rethrown)
|
||||
VERIFY( caught_system_error );
|
||||
}
|
||||
|
||||
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 new type,
|
||||
// so e1 was an object of that new 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();
|
||||
}
|
@ -50,18 +50,11 @@ void test02()
|
||||
ios.pword(1) = v;
|
||||
VERIFY( ios.pword(1) == v );
|
||||
|
||||
// The library throws the new definition of std::ios::failure
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
typedef std::ios_base::failure exception_type;
|
||||
#else
|
||||
typedef std::exception exception_type;
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
v = ios.pword(max);
|
||||
}
|
||||
catch(exception_type&)
|
||||
catch(std::ios_base::failure&)
|
||||
{
|
||||
// Ok.
|
||||
VERIFY( ios.bad() );
|
||||
@ -80,7 +73,7 @@ void test02()
|
||||
{
|
||||
v = ios.pword(std::numeric_limits<int>::max());
|
||||
}
|
||||
catch(exception_type&)
|
||||
catch(std::ios_base::failure&)
|
||||
{
|
||||
// Ok.
|
||||
VERIFY( ios.bad() );
|
||||
@ -99,7 +92,7 @@ void test02()
|
||||
{
|
||||
l = ios.iword(max);
|
||||
}
|
||||
catch(exception_type&)
|
||||
catch(std::ios_base::failure&)
|
||||
{
|
||||
// Ok.
|
||||
VERIFY( ios.bad() );
|
||||
@ -118,7 +111,7 @@ void test02()
|
||||
{
|
||||
l = ios.iword(std::numeric_limits<int>::max());
|
||||
}
|
||||
catch(exception_type&)
|
||||
catch(std::ios_base::failure&)
|
||||
{
|
||||
// Ok.
|
||||
VERIFY( ios.bad() );
|
||||
|
Loading…
Reference in New Issue
Block a user