<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Jun 24, 2026 at 8:00 PM Jonathan Wakely <<a href="mailto:jwakely@redhat.com">jwakely@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The signature of iconv in SUSv2 and legacy systems used const char** for<br>
the second parameter. We already have a workaround for this in the<br>
<ext/codecvt_specializations.h> header, but were not handling this in<br>
src/c++20/format.cc when using iconv.<br>
<br>
Define a concept to check that we can call iconv with a char** and then<br>
use that to decide which type we cast the input pointer to.<br>
<br>
libstdc++-v3/ChangeLog:<br>
<br>
        PR libstdc++/125956<br>
        * src/c++20/format.cc [_GLIBCXX_HAVE_ICONV] (iconv_input): New<br>
        concept.<br>
        (__encoding::conv) [_GLIBCXX_HAVE_ICONV]: Use iconv_input to<br>
        decide which type to cast the input pointer to.<br>
---<br>
<br>
Tested x86_64-linux.<br></blockquote><div>LGTM. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
 libstdc++-v3/src/c++20/format.cc | 12 +++++++++++-<br>
 1 file changed, 11 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/libstdc++-v3/src/c++20/format.cc b/libstdc++-v3/src/c++20/format.cc<br>
index 6967d53259da..719d019bc91f 100644<br>
--- a/libstdc++-v3/src/c++20/format.cc<br>
+++ b/libstdc++-v3/src/c++20/format.cc<br>
@@ -58,6 +58,15 @@ struct mutex<br>
 };<br>
 #endif<br>
<br>
+#ifdef _GLIBCXX_HAVE_ICONV<br>
+// Detect whether type T* can be used as the second argument to iconv.<br>
+// SUSv2 used 'const char**', but POSIX.1-2003 uses 'char**'.<br>
+template<typename T><br>
+  concept iconv_input = requires (::iconv_t cd, T in, size_t n, char** out) {<br>
+    ::iconv(cd, &in, &n, out, &n);<br>
+  };<br>
+#endif<br>
+<br>
 // A non-standard locale::facet that caches the locale's std::text_encoding<br>
 // and an iconv descriptor for converting from that encoding to UTF-8.<br>
 struct __encoding : locale::facet<br>
@@ -111,8 +120,9 @@ struct __encoding : locale::facet<br>
     bool done = false;<br>
<br>
     auto overwrite = [&](char* p, size_t n) {<br>
+      using input_t = __conditional_t<iconv_input<char*>, char*, const char*>;<br>
       auto inbytes<br>
-       = const_cast<char*>(input.data()) + input.size() - inbytesleft;<br>
+       = const_cast<input_t>(input.data()) + input.size() - inbytesleft;<br>
       char* outbytes = p + written;<br>
       size_t outbytesleft = n - written;<br>
       size_t res = ::iconv(_M_cd, &inbytes, &inbytesleft,<br>
-- <br>
2.54.0<br>
<br>
</blockquote></div></div>