[patch] Define new std::ios_base::failure with abi_tag("cxx11")

Tom de Vries Tom_deVries@mentor.com
Mon Nov 24 17:02:00 GMT 2014


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)
>



More information about the Gcc-patches mailing list