From d7487e2ae8666f071cb841a845e1e8770b4f9f67 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 3 Aug 2018 13:53:34 +0100 Subject: [PATCH] Add workaround for non-unique errno values on AIX * src/c++11/system_error.cc (system_error_category::default_error_condition): Add workaround for ENOTEMPTY and EEXIST having the same value on AIX. * testsuite/19_diagnostics/error_category/system_category.cc: Add extra testcases for EDOM, EILSEQ, ERANGE, EEXIST and ENOTEMPTY. From-SVN: r263289 --- libstdc++-v3/ChangeLog | 8 ++++ libstdc++-v3/src/c++11/system_error.cc | 3 +- .../error_category/system_category.cc | 37 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8d7306a9749..94ab41b482f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2018-08-03 Jonathan Wakely + + * src/c++11/system_error.cc + (system_error_category::default_error_condition): Add workaround for + ENOTEMPTY and EEXIST having the same value on AIX. + * testsuite/19_diagnostics/error_category/system_category.cc: Add + extra testcases for EDOM, EILSEQ, ERANGE, EEXIST and ENOTEMPTY. + 2018-08-01 Jonathan Wakely * configure: Regenerate. diff --git a/libstdc++-v3/src/c++11/system_error.cc b/libstdc++-v3/src/c++11/system_error.cc index 82b4cb5f98c..07f44c0af9c 100644 --- a/libstdc++-v3/src/c++11/system_error.cc +++ b/libstdc++-v3/src/c++11/system_error.cc @@ -241,7 +241,8 @@ namespace #ifdef ENOTDIR case ENOTDIR: #endif -#ifdef ENOTEMPTY +#if defined ENOTEMPTY && (!defined EEXIST || ENOTEMPTY != EEXIST) + // AIX sometimes uses the same value for EEXIST and ENOTEMPTY case ENOTEMPTY: #endif #ifdef ENOTRECOVERABLE diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc b/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc index 6076d735513..77cd9c5df83 100644 --- a/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc +++ b/libstdc++-v3/testsuite/19_diagnostics/error_category/system_category.cc @@ -34,6 +34,22 @@ test02() const std::error_category& cat = std::system_category(); std::error_condition cond; + // As of 2011, ISO C only defines EDOM, EILSEQ and ERANGE: + cond = cat.default_error_condition(EDOM); + VERIFY( cond.value() == EDOM ); + VERIFY( cond == std::errc::argument_out_of_domain ); + VERIFY( cond.category() == std::generic_category() ); + cond = cat.default_error_condition(EILSEQ); + VERIFY( cond.value() == EILSEQ ); + VERIFY( cond == std::errc::illegal_byte_sequence ); + VERIFY( cond.category() == std::generic_category() ); + cond = cat.default_error_condition(ERANGE); + VERIFY( cond.value() == ERANGE ); + VERIFY( cond == std::errc::result_out_of_range ); + VERIFY( cond.category() == std::generic_category() ); + + // EBADF and EACCES are defined on all targets, + // according to config/os/*/error_constants.h cond = cat.default_error_condition(EBADF); VERIFY( cond.value() == EBADF ); VERIFY( cond == std::errc::bad_file_descriptor ); @@ -52,8 +68,29 @@ test02() VERIFY( cond.category() == cat ); // PR libstdc++/60555 + VERIFY( std::error_code(EDOM, cat) == std::errc::argument_out_of_domain ); + VERIFY( std::error_code(EILSEQ, cat) == std::errc::illegal_byte_sequence ); + VERIFY( std::error_code(ERANGE, cat) == std::errc::result_out_of_range ); VERIFY( std::error_code(EBADF, cat) == std::errc::bad_file_descriptor ); VERIFY( std::error_code(EACCES, cat) == std::errc::permission_denied ); + + // As shown at https://gcc.gnu.org/ml/libstdc++/2018-08/msg00018.html + // these two error codes might have the same value on AIX, but we still + // expect both to be matched by system_category and so use generic_category: +#ifdef EEXIST + cond = cat.default_error_condition(EEXIST); + VERIFY( cond.value() == EEXIST ); + VERIFY( cond == std::errc::file_exists ); + VERIFY( cond.category() == std::generic_category() ); + VERIFY( std::error_code(EEXIST, cat) == std::errc::file_exists ); +#endif +#ifdef ENOTEMPTY + cond = cat.default_error_condition(ENOTEMPTY); + VERIFY( cond.value() == ENOTEMPTY ); + VERIFY( cond == std::errc::directory_not_empty ); + VERIFY( cond.category() == std::generic_category() ); + VERIFY( std::error_code(ENOTEMPTY, cat) == std::errc::directory_not_empty ); +#endif } void -- 2.30.2