aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-10-11 09:40:38 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2024-10-11 15:48:17 +0100
commit4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b (patch)
tree33b421643faf22d7d7ef29ef7dec1eed4c05b955
parentc10b442ee48484c1d15db2c91deac501b7e0b14e (diff)
downloadgcc-4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b.zip
gcc-4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b.tar.gz
gcc-4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b.tar.bz2
libstdc++: Fix localized %c formatting for <chrono> [PR117085]
When formatting a time point with %c we call std::vformat_to using the formatting locale's D_T_FMT string, but we weren't adding the L option to the format string. This meant we always interpreted D_T_FMT in the C locale, instead of using the formatting locale as obviously intended when %c is used. libstdc++-v3/ChangeLog: PR libstdc++/117085 * include/bits/chrono_io.h (__formatter_chrono::_M_c): Add L option to format string. * testsuite/std/time/format.cc: Move to... * testsuite/std/time/format/format.cc: ...here. * testsuite/std/time/format_localized.cc: Move to... * testsuite/std/time/format/localized.cc: ...here. * testsuite/std/time/format/pr117085.cc: New test.
-rw-r--r--libstdc++-v3/include/bits/chrono_io.h14
-rw-r--r--libstdc++-v3/testsuite/std/time/format/format.cc (renamed from libstdc++-v3/testsuite/std/time/format.cc)0
-rw-r--r--libstdc++-v3/testsuite/std/time/format/localized.cc (renamed from libstdc++-v3/testsuite/std/time/format_localized.cc)0
-rw-r--r--libstdc++-v3/testsuite/std/time/format/pr117085.cc19
4 files changed, 27 insertions, 6 deletions
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 652e88f..8c02658 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -893,17 +893,19 @@ namespace __format
// %c Locale's date and time representation.
// %Ec Locale's alternate date and time representation.
+ basic_string<_CharT> __fmt;
auto __t = _S_floor_seconds(__tt);
locale __loc = _M_locale(__ctx);
const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
const _CharT* __formats[2];
__tp._M_date_time_formats(__formats);
- const _CharT* __rep = __formats[__mod];
- if (!*__rep) [[unlikely]]
- __rep = _GLIBCXX_WIDEN("%a %b %e %T %Y");
- basic_string<_CharT> __fmt(_S_empty_spec);
- __fmt.insert(1u, 1u, _S_colon);
- __fmt.insert(2u, __rep);
+ if (*__formats[__mod]) [[likely]]
+ {
+ __fmt = _GLIBCXX_WIDEN("{:L}");
+ __fmt.insert(3u, __formats[__mod]);
+ }
+ else
+ __fmt = _GLIBCXX_WIDEN("{:L%a %b %e %T %Y}");
return std::vformat_to(std::move(__out), __loc, __fmt,
std::make_format_args<_FormatContext>(__t));
}
diff --git a/libstdc++-v3/testsuite/std/time/format.cc b/libstdc++-v3/testsuite/std/time/format/format.cc
index d6e3583..d6e3583 100644
--- a/libstdc++-v3/testsuite/std/time/format.cc
+++ b/libstdc++-v3/testsuite/std/time/format/format.cc
diff --git a/libstdc++-v3/testsuite/std/time/format_localized.cc b/libstdc++-v3/testsuite/std/time/format/localized.cc
index 393d0d2..393d0d2 100644
--- a/libstdc++-v3/testsuite/std/time/format_localized.cc
+++ b/libstdc++-v3/testsuite/std/time/format/localized.cc
diff --git a/libstdc++-v3/testsuite/std/time/format/pr117085.cc b/libstdc++-v3/testsuite/std/time/format/pr117085.cc
new file mode 100644
index 0000000..99ef838
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/format/pr117085.cc
@@ -0,0 +1,19 @@
+// { dg-do run { target c++20 } }
+// { dg-require-namedlocale "fr_FR.ISO8859-1" }
+
+#include <chrono>
+#include <locale>
+#include <testsuite_hooks.h>
+
+void
+test_c()
+{
+ std::locale::global(std::locale(ISO_8859(1,fr_FR)));
+ auto s = std::format("{:L%c}", std::chrono::sys_seconds());
+ VERIFY( ! s.starts_with("Thu") );
+}
+
+int main()
+{
+ test_c();
+}