Message ID | 20141114121829.GG5191@redhat.com |
---|---|
State | New |
Headers | show |
On 14-11-14 13:18, Jonathan Wakely wrote: > This adds system_error support to iostreams, including the required > base class changes to std::ios_base::failure. The abi_tag is used to > make it a distinct type. This changes the type of I/O exceptions > thrown by the library but exceptions are very rarely used with > iostreams. > > Tested powerpc64-linux and x86_64-linux > I'm running into this failure with a non-bootstrap build from trunk. Could this be related? ... 2 incompatible symbols 0 _ZNSt8ios_base7failureB5cxx11C1ERKSsRKSt10error_code std::ios_base::failure[abi:cxx11]::cxx11(std::string const&, std::error_code const&) version status: incompatible GLIBCXX_3.4 type: function status: added 1 _ZNSt8ios_base7failureB5cxx11C2ERKSsRKSt10error_code std::ios_base::failure[abi:cxx11]::cxx11(std::string const&, std::error_code const&) version status: incompatible GLIBCXX_3.4 type: function status: added ==== libstdc++-v3 check-abi Summary ==== # of added symbols: 143 # of missing symbols: 0 # of undesignated symbols: 2 # of incompatible symbols: 2 using: baseline_symbols.txt FAIL: libstdc++-abi/abi_check ... Thanks, - Tom > patch.txt > > > commit 8f8279579e72423450eb3ff744d9102f7b891d8d > Author: Jonathan Wakely<jwakely@redhat.com> > Date: Thu Nov 13 19:30:15 2014 +0000 > > Define C++11 version of std::ios_base::failure. > > * 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.. > > diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver > index bd44bcc..78f3e77 100644 > --- a/libstdc++-v3/config/abi/pre/gnu.ver > +++ b/libstdc++-v3/config/abi/pre/gnu.ver > @@ -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; > > diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h > index 5e33b81..8e60059 100644 > --- a/libstdc++-v3/include/bits/ios_base.h > +++ b/libstdc++-v3/include/bits/ios_base.h > @@ -40,6 +40,12 @@ > #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 > /** > diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error > index 4ec83d7..ed17f55 100644 > --- a/libstdc++-v3/include/std/system_error > +++ b/libstdc++-v3/include/std/system_error > @@ -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()), > diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am > index c8507ce..71306db 100644 > --- a/libstdc++-v3/src/c++11/Makefile.am > +++ b/libstdc++-v3/src/c++11/Makefile.am > @@ -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 > 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 > index 0000000..143d70e > --- /dev/null > +++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc > @@ -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 > diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc > index 9d32e51..0f45178 100644 > --- a/libstdc++-v3/src/c++98/ios_failure.cc > +++ b/libstdc++-v3/src/c++98/ios_failure.cc > @@ -23,9 +23,10 @@ > //<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 > index 0000000..a3276e1 > --- /dev/null > +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc > @@ -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(); > +} > diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc > index 07be43b..a50c798 100644 > --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc > +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc > @@ -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) > diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc > index 334c8e1..e16ef7c 100644 > --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc > +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc > @@ -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 ); } > } > diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc > index b9af939..abbbcca 100644 > --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc > +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc > @@ -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) > diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc > index a2bd37c..99ee17d 100644 > --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc > +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc > @@ -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) >
On 24/11/14 17:48 +0100, Tom de Vries wrote: >On 14-11-14 13:18, Jonathan Wakely wrote: >>This adds system_error support to iostreams, including the required >>base class changes to std::ios_base::failure. The abi_tag is used to >>make it a distinct type. This changes the type of I/O exceptions >>thrown by the library but exceptions are very rarely used with >>iostreams. >> >>Tested powerpc64-linux and x86_64-linux >> > >I'm running into this failure with a non-bootstrap build from trunk. Is this on i686? >Could this be related? Yes, definitely. I was aware of the failures but hadn't been able to reproduce them. With the info below I should be able to fix it, thanks. >2 incompatible symbols >0 >_ZNSt8ios_base7failureB5cxx11C1ERKSsRKSt10error_code >std::ios_base::failure[abi:cxx11]::cxx11(std::string const&, std::error_code const&) >version status: incompatible >GLIBCXX_3.4 >type: function >status: added > > >1 >_ZNSt8ios_base7failureB5cxx11C2ERKSsRKSt10error_code >std::ios_base::failure[abi:cxx11]::cxx11(std::string const&, std::error_code const&) >version status: incompatible >GLIBCXX_3.4 >type: function >status: added
On 24-11-14 18:12, Jonathan Wakely wrote: > On 24/11/14 17:48 +0100, Tom de Vries wrote: >> On 14-11-14 13:18, Jonathan Wakely wrote: >>> This adds system_error support to iostreams, including the required >>> base class changes to std::ios_base::failure. The abi_tag is used to >>> make it a distinct type. This changes the type of I/O exceptions >>> thrown by the library but exceptions are very rarely used with >>> iostreams. >>> >>> Tested powerpc64-linux and x86_64-linux >>> >> >> I'm running into this failure with a non-bootstrap build from trunk. > > Is this on i686? > No, x86_64-unknown-linux-gnu. >> Could this be related? > > Yes, definitely. > > I was aware of the failures but hadn't been able to reproduce them. > With the info below I should be able to fix it, thanks. > Great :) Thanks, - Tom > >> 2 incompatible symbols >> 0 >> _ZNSt8ios_base7failureB5cxx11C1ERKSsRKSt10error_code >> std::ios_base::failure[abi:cxx11]::cxx11(std::string const&, std::error_code >> const&) >> version status: incompatible >> GLIBCXX_3.4 >> type: function >> status: added >> >> >> 1 >> _ZNSt8ios_base7failureB5cxx11C2ERKSsRKSt10error_code >> std::ios_base::failure[abi:cxx11]::cxx11(std::string const&, std::error_code >> const&) >> version status: incompatible >> GLIBCXX_3.4 >> type: function >> status: added
commit 8f8279579e72423450eb3ff744d9102f7b891d8d Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Nov 13 19:30:15 2014 +0000 Define C++11 version of std::ios_base::failure. * 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.. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index bd44bcc..78f3e77 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -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; diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 5e33b81..8e60059 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -40,6 +40,12 @@ #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 /** diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error index 4ec83d7..ed17f55 100644 --- a/libstdc++-v3/include/std/system_error +++ b/libstdc++-v3/include/std/system_error @@ -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()), diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am index c8507ce..71306db 100644 --- a/libstdc++-v3/src/c++11/Makefile.am +++ b/libstdc++-v3/src/c++11/Makefile.am @@ -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 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 index 0000000..143d70e --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc @@ -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 diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc index 9d32e51..0f45178 100644 --- a/libstdc++-v3/src/c++98/ios_failure.cc +++ b/libstdc++-v3/src/c++98/ios_failure.cc @@ -23,9 +23,10 @@ // <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 index 0000000..a3276e1 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc @@ -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(); +} diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc index 07be43b..a50c798 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-1.cc @@ -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) diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc index 334c8e1..e16ef7c 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-2.cc @@ -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 ); } } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc index b9af939..abbbcca 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-3.cc @@ -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) diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc index a2bd37c..99ee17d 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/what-big.cc @@ -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)