mirror of git://gcc.gnu.org/git/gcc.git
PR libstdc++/60555 std::system_category() should recognise POSIX errno values
PR libstdc++/60555 * src/c++11/system_error.cc (system_error_category::default_error_condition): New override to check for POSIX errno values. * testsuite/19_diagnostics/error_category/generic_category.cc: New * testsuite/19_diagnostics/error_category/system_category.cc: New test. From-SVN: r263210
This commit is contained in:
parent
e335138dae
commit
5ecfbf82a4
|
|
@ -1,3 +1,13 @@
|
|||
2018-08-01 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/60555
|
||||
* src/c++11/system_error.cc
|
||||
(system_error_category::default_error_condition): New override to
|
||||
check for POSIX errno values.
|
||||
* testsuite/19_diagnostics/error_category/generic_category.cc: New
|
||||
* testsuite/19_diagnostics/error_category/system_category.cc: New
|
||||
test.
|
||||
|
||||
2018-07-31 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/86751
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <system_error>
|
||||
#include <bits/functexcept.h>
|
||||
#include <limits>
|
||||
#include <errno.h>
|
||||
#undef __sso_string
|
||||
|
||||
namespace
|
||||
|
|
@ -65,6 +66,260 @@ namespace
|
|||
// _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
|
||||
return string(strerror(i));
|
||||
}
|
||||
|
||||
virtual std::error_condition
|
||||
default_error_condition(int ev) const noexcept
|
||||
{
|
||||
switch (ev)
|
||||
{
|
||||
// List of errno macros from [cerrno.syn].
|
||||
// C11 only defines EDOM, EILSEQ and ERANGE, the rest are from POSIX.
|
||||
// They expand to integer constant expressions with type int,
|
||||
// and distinct positive values, suitable for use in #if directives.
|
||||
// POSIX adds more macros (but they're not defined on all targets,
|
||||
// see config/os/*/error_constants.h), and POSIX allows
|
||||
// EAGAIN == EWOULDBLOCK and ENOTSUP == EOPNOTSUPP.
|
||||
|
||||
#ifdef E2BIG
|
||||
case E2BIG:
|
||||
#endif
|
||||
#ifdef EACCES
|
||||
case EACCES:
|
||||
#endif
|
||||
#ifdef EADDRINUSE
|
||||
case EADDRINUSE:
|
||||
#endif
|
||||
#ifdef EADDRNOTAVAIL
|
||||
case EADDRNOTAVAIL:
|
||||
#endif
|
||||
#ifdef EAFNOSUPPORT
|
||||
case EAFNOSUPPORT:
|
||||
#endif
|
||||
#ifdef EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#ifdef EALREADY
|
||||
case EALREADY:
|
||||
#endif
|
||||
#ifdef EBADF
|
||||
case EBADF:
|
||||
#endif
|
||||
#ifdef EBADMSG
|
||||
case EBADMSG:
|
||||
#endif
|
||||
#ifdef EBUSY
|
||||
case EBUSY:
|
||||
#endif
|
||||
#ifdef ECANCELED
|
||||
case ECANCELED:
|
||||
#endif
|
||||
#ifdef ECHILD
|
||||
case ECHILD:
|
||||
#endif
|
||||
#ifdef ECONNABORTED
|
||||
case ECONNABORTED:
|
||||
#endif
|
||||
#ifdef ECONNREFUSED
|
||||
case ECONNREFUSED:
|
||||
#endif
|
||||
#ifdef ECONNRESET
|
||||
case ECONNRESET:
|
||||
#endif
|
||||
#ifdef EDEADLK
|
||||
case EDEADLK:
|
||||
#endif
|
||||
#ifdef EDESTADDRREQ
|
||||
case EDESTADDRREQ:
|
||||
#endif
|
||||
case EDOM:
|
||||
#ifdef EEXIST
|
||||
case EEXIST:
|
||||
#endif
|
||||
#ifdef EFAULT
|
||||
case EFAULT:
|
||||
#endif
|
||||
#ifdef EFBIG
|
||||
case EFBIG:
|
||||
#endif
|
||||
#ifdef EHOSTUNREACH
|
||||
case EHOSTUNREACH:
|
||||
#endif
|
||||
#ifdef EIDRM
|
||||
case EIDRM:
|
||||
#endif
|
||||
case EILSEQ:
|
||||
#ifdef EINPROGRESS
|
||||
case EINPROGRESS:
|
||||
#endif
|
||||
#ifdef EINTR
|
||||
case EINTR:
|
||||
#endif
|
||||
#ifdef EINVAL
|
||||
case EINVAL:
|
||||
#endif
|
||||
#ifdef EIO
|
||||
case EIO:
|
||||
#endif
|
||||
#ifdef EISCONN
|
||||
case EISCONN:
|
||||
#endif
|
||||
#ifdef EISDIR
|
||||
case EISDIR:
|
||||
#endif
|
||||
#ifdef ELOOP
|
||||
case ELOOP:
|
||||
#endif
|
||||
#ifdef EMFILE
|
||||
case EMFILE:
|
||||
#endif
|
||||
#ifdef EMLINK
|
||||
case EMLINK:
|
||||
#endif
|
||||
#ifdef EMSGSIZE
|
||||
case EMSGSIZE:
|
||||
#endif
|
||||
#ifdef ENAMETOOLONG
|
||||
case ENAMETOOLONG:
|
||||
#endif
|
||||
#ifdef ENETDOWN
|
||||
case ENETDOWN:
|
||||
#endif
|
||||
#ifdef ENETRESET
|
||||
case ENETRESET:
|
||||
#endif
|
||||
#ifdef ENETUNREACH
|
||||
case ENETUNREACH:
|
||||
#endif
|
||||
#ifdef ENFILE
|
||||
case ENFILE:
|
||||
#endif
|
||||
#ifdef ENOBUFS
|
||||
case ENOBUFS:
|
||||
#endif
|
||||
#ifdef ENODATA
|
||||
case ENODATA:
|
||||
#endif
|
||||
#ifdef ENODEV
|
||||
case ENODEV:
|
||||
#endif
|
||||
#ifdef ENOENT
|
||||
case ENOENT:
|
||||
#endif
|
||||
#ifdef ENOEXEC
|
||||
case ENOEXEC:
|
||||
#endif
|
||||
#ifdef ENOLCK
|
||||
case ENOLCK:
|
||||
#endif
|
||||
#ifdef ENOLINK
|
||||
case ENOLINK:
|
||||
#endif
|
||||
#ifdef ENOMEM
|
||||
case ENOMEM:
|
||||
#endif
|
||||
#ifdef ENOMSG
|
||||
case ENOMSG:
|
||||
#endif
|
||||
#ifdef ENOPROTOOPT
|
||||
case ENOPROTOOPT:
|
||||
#endif
|
||||
#ifdef ENOSPC
|
||||
case ENOSPC:
|
||||
#endif
|
||||
#ifdef ENOSR
|
||||
case ENOSR:
|
||||
#endif
|
||||
#ifdef ENOSTR
|
||||
case ENOSTR:
|
||||
#endif
|
||||
#ifdef ENOSYS
|
||||
case ENOSYS:
|
||||
#endif
|
||||
#ifdef ENOTCONN
|
||||
case ENOTCONN:
|
||||
#endif
|
||||
#ifdef ENOTDIR
|
||||
case ENOTDIR:
|
||||
#endif
|
||||
#ifdef ENOTEMPTY
|
||||
case ENOTEMPTY:
|
||||
#endif
|
||||
#ifdef ENOTRECOVERABLE
|
||||
case ENOTRECOVERABLE:
|
||||
#endif
|
||||
#ifdef ENOTSOCK
|
||||
case ENOTSOCK:
|
||||
#endif
|
||||
#ifdef ENOTSUP
|
||||
case ENOTSUP:
|
||||
#endif
|
||||
#ifdef ENOTTY
|
||||
case ENOTTY:
|
||||
#endif
|
||||
#ifdef ENXIO
|
||||
case ENXIO:
|
||||
#endif
|
||||
#if defined EOPNOTSUPP && (!defined ENOTSUP || EOPNOTSUPP != ENOTSUP)
|
||||
case EOPNOTSUPP:
|
||||
#endif
|
||||
#ifdef EOVERFLOW
|
||||
case EOVERFLOW:
|
||||
#endif
|
||||
#ifdef EOWNERDEAD
|
||||
case EOWNERDEAD:
|
||||
#endif
|
||||
#ifdef EPERM
|
||||
case EPERM:
|
||||
#endif
|
||||
#ifdef EPIPE
|
||||
case EPIPE:
|
||||
#endif
|
||||
#ifdef EPROTO
|
||||
case EPROTO:
|
||||
#endif
|
||||
#ifdef EPROTONOSUPPORT
|
||||
case EPROTONOSUPPORT:
|
||||
#endif
|
||||
#ifdef EPROTOTYPE
|
||||
case EPROTOTYPE:
|
||||
#endif
|
||||
case ERANGE:
|
||||
#ifdef EROFS
|
||||
case EROFS:
|
||||
#endif
|
||||
#ifdef ESPIPE
|
||||
case ESPIPE:
|
||||
#endif
|
||||
#ifdef ESRCH
|
||||
case ESRCH:
|
||||
#endif
|
||||
#ifdef ETIME
|
||||
case ETIME:
|
||||
#endif
|
||||
#ifdef ETIMEDOUT
|
||||
case ETIMEDOUT:
|
||||
#endif
|
||||
#ifdef ETXTBSY
|
||||
case ETXTBSY:
|
||||
#endif
|
||||
#if defined EWOULDBLOCK && (!defined EAGAIN || EWOULDBLOCK != EAGAIN)
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
#ifdef EXDEV
|
||||
case EXDEV:
|
||||
#endif
|
||||
return std::error_condition(ev, std::generic_category());
|
||||
|
||||
/* Additional system-dependent mappings from non-standard error codes
|
||||
* to one of the POSIX values above would go here, e.g.
|
||||
case EBLAH:
|
||||
return std::error_condition(EINVAL, std::generic_category());
|
||||
*/
|
||||
|
||||
default:
|
||||
return std::error_condition(ev, std::system_category());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const generic_error_category generic_category_instance{};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
// 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-do run { target c++11 } }
|
||||
|
||||
#include <system_error>
|
||||
#include <locale>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
const char* name = std::generic_category().name();
|
||||
VERIFY( name == std::string("generic") );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
const std::error_category& cat = std::generic_category();
|
||||
std::error_condition cond;
|
||||
|
||||
cond = cat.default_error_condition(EBADF);
|
||||
VERIFY( cond.value() == EBADF );
|
||||
VERIFY( cond == std::errc::bad_file_descriptor );
|
||||
VERIFY( cond.category() == std::generic_category() );
|
||||
cond = cat.default_error_condition(EACCES);
|
||||
VERIFY( cond.value() == EACCES );
|
||||
VERIFY( cond == std::errc::permission_denied );
|
||||
VERIFY( cond.category() == std::generic_category() );
|
||||
|
||||
// PR libstdc++/60555
|
||||
VERIFY( std::error_code(EBADF, cat) == std::errc::bad_file_descriptor );
|
||||
VERIFY( std::error_code(EACCES, cat) == std::errc::permission_denied );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
// set "C" locale to get expected message
|
||||
auto loc = std::locale::global(std::locale::classic());
|
||||
|
||||
std::string msg = std::generic_category().message(EBADF);
|
||||
VERIFY( msg.find("file") != std::string::npos );
|
||||
|
||||
std::locale::global(loc);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// 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-do run { target c++11 } }
|
||||
|
||||
#include <system_error>
|
||||
#include <locale>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
const char* name = std::system_category().name();
|
||||
VERIFY( name == std::string("system") );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
const std::error_category& cat = std::system_category();
|
||||
std::error_condition cond;
|
||||
|
||||
cond = cat.default_error_condition(EBADF);
|
||||
VERIFY( cond.value() == EBADF );
|
||||
VERIFY( cond == std::errc::bad_file_descriptor );
|
||||
VERIFY( cond.category() == std::generic_category() );
|
||||
cond = cat.default_error_condition(EACCES);
|
||||
VERIFY( cond.value() == EACCES );
|
||||
VERIFY( cond == std::errc::permission_denied );
|
||||
VERIFY( cond.category() == std::generic_category() );
|
||||
|
||||
// All POSIX errno values are positive:
|
||||
cond = cat.default_error_condition(-1);
|
||||
VERIFY( cond.value() == -1 );
|
||||
VERIFY( cond.category() == cat );
|
||||
cond = cat.default_error_condition(-99);
|
||||
VERIFY( cond.value() == -99 );
|
||||
VERIFY( cond.category() == cat );
|
||||
|
||||
// PR libstdc++/60555
|
||||
VERIFY( std::error_code(EBADF, cat) == std::errc::bad_file_descriptor );
|
||||
VERIFY( std::error_code(EACCES, cat) == std::errc::permission_denied );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
// set "C" locale to get expected message
|
||||
auto loc = std::locale::global(std::locale::classic());
|
||||
|
||||
std::string msg = std::system_category().message(EBADF);
|
||||
VERIFY( msg.find("file") != std::string::npos );
|
||||
|
||||
std::locale::global(loc);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
||||
Loading…
Reference in New Issue