https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104883
Bug ID: 104883
Summary: <system_error> should define all std::errc enumerators
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
Currently we only define std::errc enumerators when the OS defines the
corresponding errno macro:
#ifdef EOVERFLOW
value_too_large = EOVERFLOW,
#endif
Which causes errors when we rely on that being present, e.g. for AVR:
/home/jwakely/src/gcc/build-avr/avr/libstdc++-v3/include/charconv: In function
‘std::to_chars_result std::__detail::__to_chars(char*, char*, _Tp, int)’:
/home/jwakely/src/gcc/build-avr/avr/libstdc++-v3/include/charconv:132:28:
error: ‘value_too_large’ is not a member of ‘std::errc’; did you mean
‘file_too_large’?
132 | __res.ec = errc::value_too_large;
| ^~~~~~~~~~~~~~~
| file_too_large
And src/filesystem/ops-common.h does this to workaround the fact that
std::errc::not_supported isn't always defined:
inline error_code
__unsupported() noexcept
{
#if defined ENOTSUP
return std::make_error_code(std::errc::not_supported);
#elif defined EOPNOTSUPP
// This is supposed to be for socket operations
return std::make_error_code(std::errc::operation_not_supported);
#else
return std::make_error_code(std::errc::invalid_argument);
#endif
}
We should consider defining all the enumerators unconditionally, picking values
outside the range used by the OS for <errno.h> constants, e.g.
#ifdef EOVERFLOW
value_too_large = EOVERFLOW,
#else
value_too_large = 1001,
#endif
The tricky part is picking a value range that doesn't clash with the OS. For
the OS-specific headers such as config/os/mingw32-w64/error_constants.h we can
just inspect <errno.h> and make an educated choice. For
config/os/generic/error_constants.h maybe we want to do something in configure
or with the preprocessor to find the largest value among all the errno macros
that *are* defined, and add 100. Or just take a gamble and assume the OS uses
small numbers and we can start from 1000, or 32000, or something.