From: Jonathan Wakely Date: Thu, 8 Oct 2020 13:03:52 +0000 (+0100) Subject: libstdc++: Add C++11 member functions for ios::failure in old ABI X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f997b67550144c6c0562f94c9b9cb932125d0444;p=gcc.git libstdc++: Add C++11 member functions for ios::failure in old ABI The new constructors that C++11 added to std::ios_base::failure were missing for the old ABI. This adds them, but just ignores the std::error_code argument (because there's nowhere to store it). This also adds a code() member, which should be provided by the std::system_error base class, but that base class isn't present in the old ABI. This allows the old ios::failure to be used in code that expects the new API, although with reduced functionality. libstdc++-v3/ChangeLog: * include/bits/ios_base.h (ios_base::failure): Add constructors takeing error_code argument. Add code() member function. * testsuite/27_io/ios_base/failure/cxx11.cc: Allow test to run for the old ABI but do not check for derivation from std::system_error. * testsuite/27_io/ios_base/failure/error_code.cc: New test. --- diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 4ac026547b4..729ebd1768e 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -289,6 +289,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual const char* what() const throw(); +#if __cplusplus >= 201103L + // Define the new members required by C++11, + // even though the error_code cannot be stored. + + explicit + failure(const string& __s, const error_code&) noexcept + : failure(__s) + { } + + explicit + failure(const char* __s, const error_code& = error_code{}) + : failure(string(__s)) + { } + + // Stand-in for system_error::code() but returning by value. + error_code code() const noexcept { return error_code{}; } +#endif + private: string _M_msg; }; diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc index b78db49ed5a..06827f662c0 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc @@ -16,14 +16,15 @@ // . // { dg-do run { target c++11 } } -// { dg-require-effective-target cxx11-abi } #include #include using test_type = std::ios_base::failure; +#if _GLIBCXX_USE_CXX11_ABI static_assert( std::is_base_of::value, "base" ); +#endif void test01() diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/error_code.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/error_code.cc new file mode 100644 index 00000000000..a377dc047c9 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/error_code.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2020 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +void +test01() +{ + std::error_code ec, def_ec; +#if _GLIBCXX_USE_CXX11_ABI + // For the new ABI code() should return the constructor argument. + ec = std::make_error_code(std::errc::executable_format_error); + def_ec = std::io_errc::stream; +#else + // For the old ABI code() always returns a default-constructed error_code. +#endif + std::ios_base::failure e1("string literal"); + VERIFY( e1.code() == def_ec ); + std::ios_base::failure e2(std::string("std::string")); + VERIFY( e2.code() == def_ec ); + std::ios_base::failure e3("string literal", ec); + VERIFY( e3.code() == ec ); + std::ios_base::failure e4(std::string("std::string"), ec); + VERIFY( e4.code() == ec ); +} + +int +main() +{ + test01(); +}