https://gcc.gnu.org/g:5aacef1530f52cdcafee5599ace6d6b5e76c6e89
commit r15-11341-g5aacef1530f52cdcafee5599ace6d6b5e76c6e89 Author: Jonathan Wakely <[email protected]> Date: Wed Jun 24 16:56:25 2026 +0100 libstdc++: Workaround legacy iconv signature [PR125956] The signature of iconv in SUSv2 and legacy systems used const char** for the second parameter. We already have a workaround for this in the <ext/codecvt_specializations.h> header, but were not handling this when using iconv in src/c++20/format.cc. Define a concept to check that we can call iconv with a char** and then use that to decide which type we cast the input pointer to. libstdc++-v3/ChangeLog: PR libstdc++/125956 * src/c++20/format.cc [_GLIBCXX_HAVE_ICONV] (iconv_input): New concept. (__encoding::conv) [_GLIBCXX_HAVE_ICONV]: Use iconv_input to decide which type to cast the input pointer to. Reviewed-by: Tomasz KamiĆski <[email protected]> (cherry picked from commit 83f0ad40a472d98bf1ed38b7d1c4865fdcb5e068) Diff: --- libstdc++-v3/src/c++20/format.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/src/c++20/format.cc b/libstdc++-v3/src/c++20/format.cc index 6967d53259da..719d019bc91f 100644 --- a/libstdc++-v3/src/c++20/format.cc +++ b/libstdc++-v3/src/c++20/format.cc @@ -58,6 +58,15 @@ struct mutex }; #endif +#ifdef _GLIBCXX_HAVE_ICONV +// Detect whether type T* can be used as the second argument to iconv. +// SUSv2 used 'const char**', but POSIX.1-2003 uses 'char**'. +template<typename T> + concept iconv_input = requires (::iconv_t cd, T in, size_t n, char** out) { + ::iconv(cd, &in, &n, out, &n); + }; +#endif + // A non-standard locale::facet that caches the locale's std::text_encoding // and an iconv descriptor for converting from that encoding to UTF-8. struct __encoding : locale::facet @@ -111,8 +120,9 @@ struct __encoding : locale::facet bool done = false; auto overwrite = [&](char* p, size_t n) { + using input_t = __conditional_t<iconv_input<char*>, char*, const char*>; auto inbytes - = const_cast<char*>(input.data()) + input.size() - inbytesleft; + = const_cast<input_t>(input.data()) + input.size() - inbytesleft; char* outbytes = p + written; size_t outbytesleft = n - written; size_t res = ::iconv(_M_cd, &inbytes, &inbytesleft,
