libstdc++: Move std::iostream_category() definition to new file

This fixes a missing symbol when the dual ABI is disabled, e.g. for the
versioned namespace build.

libstdc++-v3/ChangeLog:

	* src/c++11/Makefile.am: Add new source file.
	* src/c++11/Makefile.in: Regenerate.
	* src/c++11/cxx11-ios_failure.cc (iostream_category):
	Move to ...
	* src/c++11/ios_errcat.cc: New file.
	* testsuite/27_io/ios_base/failure/error_code.cc: Check that
	std::iostream_category() is defined and used for std::io_errc.
This commit is contained in:
Jonathan Wakely 2022-05-26 15:42:50 +01:00
parent 6f56efa94e
commit ae3ea143ef
5 changed files with 103 additions and 50 deletions

View File

@ -65,6 +65,7 @@ sources = \
hash_c++0x.cc \
hashtable_c++0x.cc \
ios.cc \
ios_errcat.cc \
limits.cc \
mutex.cc \
placeholders.cc \

View File

@ -130,9 +130,10 @@ am__objects_2 = ctype_configure_char.lo ctype_members.lo
am__objects_3 = chrono.lo codecvt.lo condition_variable.lo \
cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
functional.lo futex.lo future.lo hash_c++0x.lo \
hashtable_c++0x.lo ios.lo limits.lo mutex.lo placeholders.lo \
random.lo regex.lo shared_ptr.lo snprintf_lite.lo \
system_error.lo thread.lo $(am__objects_1) $(am__objects_2)
hashtable_c++0x.lo ios.lo ios_errcat.lo limits.lo mutex.lo \
placeholders.lo random.lo regex.lo shared_ptr.lo \
snprintf_lite.lo system_error.lo thread.lo $(am__objects_1) \
$(am__objects_2)
@ENABLE_DUAL_ABI_TRUE@am__objects_4 = cow-fstream-inst.lo \
@ENABLE_DUAL_ABI_TRUE@ cow-sstream-inst.lo cow-string-inst.lo \
@ENABLE_DUAL_ABI_TRUE@ cow-string-io-inst.lo \
@ -479,6 +480,7 @@ sources = \
hash_c++0x.cc \
hashtable_c++0x.cc \
ios.cc \
ios_errcat.cc \
limits.cc \
mutex.cc \
placeholders.cc \

View File

@ -42,57 +42,10 @@
# error This file should not be compiled for this configuration.
#endif
#if __has_cpp_attribute(clang::require_constant_initialization)
# define __constinit [[clang::require_constant_initialization]]
#endif
namespace
{
struct io_error_category final : std::error_category
{
const char*
name() const noexcept final
{ return "iostream"; }
_GLIBCXX_DEFAULT_ABI_TAG
std::string
message(int __ec) const final
{
std::string __msg;
switch (std::io_errc(__ec))
{
case std::io_errc::stream:
__msg = "iostream error";
break;
default:
__msg = "Unknown error";
break;
}
return __msg;
}
};
struct constant_init
{
union {
unsigned char unused;
io_error_category cat;
};
constexpr constant_init() : cat() { }
~constant_init() { /* do nothing, union member is not destroyed */ }
};
__constinit constant_init io_category_instance{};
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
const error_category&
iostream_category() noexcept
{ return io_category_instance.cat; }
ios_base::failure::failure(const string& __str)
: system_error(io_errc::stream, __str) { }

View File

@ -0,0 +1,84 @@
// std::iostream_category() definition -*- C++ -*-
// Copyright (C) 2014-2022 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.6.5 Error reporting [error.reporting]
//
#define _GLIBCXX_USE_CXX11_ABI 1
#include <ios>
#if __has_cpp_attribute(clang::require_constant_initialization)
# define __constinit [[clang::require_constant_initialization]]
#endif
namespace
{
struct io_error_category final : std::error_category
{
const char*
name() const noexcept final
{ return "iostream"; }
_GLIBCXX_DEFAULT_ABI_TAG
std::string
message(int __ec) const final
{
std::string __msg;
switch (std::io_errc(__ec))
{
case std::io_errc::stream:
__msg = "iostream error";
break;
default:
__msg = "Unknown error";
break;
}
return __msg;
}
};
struct constant_init
{
union {
unsigned char unused;
io_error_category cat;
};
constexpr constant_init() : cat() { }
~constant_init() { /* do nothing, union member is not destroyed */ }
};
__constinit constant_init io_category_instance{};
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
const error_category&
iostream_category() noexcept
{ return io_category_instance.cat; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -41,8 +41,21 @@ test01()
VERIFY( e4.code() == ec );
}
[[gnu::noinline,gnu::noipa]]
const std::error_category&
get_iostream_category()
{ return std::iostream_category(); }
void
test02()
{
auto ec = std::make_error_code(std::io_errc::stream);
VERIFY( ec.category() == get_iostream_category() );
}
int
main()
{
test01();
test02();
}