From 9184dd174635b0ec54e97d1f794ef0c3d5147f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Fri, 10 Apr 2026 10:24:19 +0200 Subject: [PATCH] libstdc++: Test for using non-ascii unicode fill with non-unicode encoding. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz Kamiński --- 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 +#include + +template +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 +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)); + // 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 + : std::formatter +{}; + +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"