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>
|
2018-07-31 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
PR libstdc++/86751
|
PR libstdc++/86751
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <bits/functexcept.h>
|
#include <bits/functexcept.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <errno.h>
|
||||||
#undef __sso_string
|
#undef __sso_string
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
@ -65,6 +66,260 @@ namespace
|
||||||
// _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
|
// _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
|
||||||
return string(strerror(i));
|
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{};
|
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