https://gcc.gnu.org/g:7e34ccf2afe3202aa89c58081e46c4a0a10de2a0

commit r16-9210-g7e34ccf2afe3202aa89c58081e46c4a0a10de2a0
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,

Reply via email to