On 02/08/18 13:05 -0400, David Edelsohn wrote:
On Thu, Aug 2, 2018 at 12:12 PM Jonathan Wakely <[email protected]> wrote:On 02/08/18 11:32 -0400, David Edelsohn wrote: >Jonathan > >This patch broke AIX bootstrap. > >/nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/system_error.cc: In >member function 'virtual std::error_condition >{anonymous}::system_error_category::default_error_condition(int) >const': >/nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/system_error.cc:245:7: >error: duplicate case value > case ENOTEMPTY: > ^~~~ >/nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/system_error.cc:136:7: >note: previously used here > case EEXIST: > ^~~~ > >AIX errno.h > >/* > * AIX returns EEXIST where 4.3BSD used ENOTEMPTY; > * but, the standards insist on unique errno values for each errno. > * A unique value is reserved for users that want to code case > * statements for systems that return either EEXIST or ENOTEMPTY. > */ >#if defined(_ALL_SOURCE) && !defined(_LINUX_SOURCE_COMPAT) >#define ENOTEMPTY EEXIST /* Directory not empty */ >#else /* not _ALL_SOURCE */ >#define ENOTEMPTY 87 >#endif /* _ALL_SOURCE */ Strange that "linux source compat" is required for POSIX conformance. >I will add _LINUX_SOURCE_COMPAT and see how bootstrap proceeds. If it >works, it also will be required in the backport. Let's just workaround the maybe-not-unique values instead: --- 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 ENOTRECOVERABLEWhatever you prefer. _LINUX_SOURCE_COMPAT seems to be working for bootstrap so far.
I've committed this to trunk. Tested x86_64-linux, powerpc64le-linux, powerpc-aix.
commit f2848bf67225467c71853921d071f3c4a94431a0 Author: Jonathan Wakely <[email protected]> Date: Fri Aug 3 13:24:06 2018 +0100 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. 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
