[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