[PATCH] libstdc++: Test for using non-ascii unicode fill with non-unicode encoding.

Jonathan Wakely jwakely@redhat.com
Tue Apr 14 10:35:18 GMT 2026


On Fri, 10 Apr 2026 at 11:07 +0200, Tomasz Kamiński wrote:
>This checks if format string using as fill character an Unicode code-point,
>that is encoded as multiple code units, is rejected when literal encoding
>is not Unicode.
>
>libstdc++-v3/ChangeLog:
>
>	* testsuite/std/format/fill.cc: New test.
>	* testsuite/std/format/fill_nonunicode.cc: New test.
>
>Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
>---
>This test fails, if we use __do_vformat_to defintion with formatters
>compiled with unicode literal encoding, from TU that uses non-literal
>encoding (fill-nonunicode).
>
>Tested on x86_64-linux. OK for trunk?
>
> libstdc++-v3/testsuite/std/format/fill.cc     | 56 +++++++++++++++++++
> .../testsuite/std/format/fill_nonunicode.cc   |  5 ++
> 2 files changed, 61 insertions(+)
> create mode 100644 libstdc++-v3/testsuite/std/format/fill.cc
> create mode 100644 libstdc++-v3/testsuite/std/format/fill_nonunicode.cc
>
>diff --git a/libstdc++-v3/testsuite/std/format/fill.cc b/libstdc++-v3/testsuite/std/format/fill.cc
>new file mode 100644
>index 00000000000..d281ec1080a
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/std/format/fill.cc
>@@ -0,0 +1,56 @@
>+// { dg-options "-fexec-charset=UTF-8 -DUNICODE_ENC" }
>+// { dg-do run { target c++20 } }
>+
>+#include <format>
>+#include <testsuite_hooks.h>
>+
>+template<typename... Args>
>+bool
>+is_format_string_for(const char* str, Args&&... args)
>+{
>+  try {
>+    (void) std::vformat(str, std::make_format_args(args...));
>+    return true;
>+  } catch (const std::format_error&) {
>+    return false;
>+  }
>+}
>+
>+template<typename T>
>+void
>+test_fill(T t)
>+{
>+  constexpr bool accept_utf8_nonascii
>+#ifdef UNICODE_ENC
>+   = true;
>+#else
>+   = false;
>+#endif
>+
>+   VERIFY(is_format_string_for("{: <}", t));
>+   VERIFY(is_format_string_for("{:Å<}", t));

Do we want -finput-charset=UTF-8 so that the character above is
interpreted correctly? The source file has a two-byte UTF-8 sequence,
\xC3\x85, which is a single character in UTF-8 or when converted to
ISO8859-1. But if the test is run with -finput-charset=ascii or
-finput-charset=iso8859-1 then those two bytes are not a single
character, the two source bytes will be interpreted as two separate
characters.

Alternatively, you could use \u00C5 and then let the compiler handle
that appropriately. I think that will still test what this is
intending to test?

>+   // U+0119 Latin Small Letter E with Ogonek
>+   VERIFY(is_format_string_for("{:\xC4\x99<}", t) == accept_utf8_nonascii);
>+   // U+2705 White Heavy Check Mark
>+   VERIFY(is_format_string_for("{:\xE2\x9C\x85<}", t) == accept_utf8_nonascii);
>+   // U+1F602 Face with Tears of Joy
>+   VERIFY(is_format_string_for("{:\xF0\x9F\x98\x82<}", t) == accept_utf8_nonascii);
>+}
>+
>+struct MyStringView : std::string_view
>+{
>+  using std::string_view::string_view;
>+};
>+
>+template<>
>+struct std::formatter<MyStringView, char>
>+  : std::formatter<std::string_view, char>
>+{};
>+
>+int main()
>+{
>+  test_fill(10);
>+  test_fill(std::string_view("test"));
>+  // Test with type stored by handle
>+  test_fill(MyStringView("test"));
>+}
>diff --git a/libstdc++-v3/testsuite/std/format/fill_nonunicode.cc b/libstdc++-v3/testsuite/std/format/fill_nonunicode.cc
>new file mode 100644
>index 00000000000..1370cf57ccd
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/std/format/fill_nonunicode.cc
>@@ -0,0 +1,5 @@
>+// { dg-options "-fexec-charset=ISO8859-1" }
>+// { dg-do run { target c++20 } }
>+// { dg-add-options no_pch }
>+
>+#include "fill.cc"
>-- 
>2.53.0
>
>



More information about the Libstdc++ mailing list