On Fri, Dec 19, 2025 at 1:50 PM Jonathan Wakely <[email protected]> wrote:
> When we extract wide characters and insert them into a stringstream to
> be parsed as a floating-point value, we should use a stringstream of
> char, not wchar_t.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/123147
> * include/bits/chrono_io.h (_Parser::operator()) <%S>: Use a
> buffer of narrow characters to be parsed by std::from_chars.
> * testsuite/std/time/parse/parse.cc: Check wchar_t parsing.
> ---
>
> Tested x86_64-linux.
> I think there are other problems in chrono::parse which also affect
> narrow characters (e.g. we don't use the precision for %NS and I think
> we use the precision wrong in general). But those are distinct from this
> fix, which just makes sure that parsing wide strings isn't ill-formed.
>
LGTM. Still this is an improvement.
>
> libstdc++-v3/include/bits/chrono_io.h | 8 ++++----
> libstdc++-v3/testsuite/std/time/parse/parse.cc | 14 ++++++++++++++
> 2 files changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/chrono_io.h
> b/libstdc++-v3/include/bits/chrono_io.h
> index 75dd532a8cb3..37a296fed7ec 100644
> --- a/libstdc++-v3/include/bits/chrono_io.h
> +++ b/libstdc++-v3/include/bits/chrono_io.h
> @@ -4977,14 +4977,14 @@ namespace __detail
> }
> else // Read fractional seconds
> {
> - basic_stringstream<_CharT> __buf;
> + stringstream __buf;
> auto __digit = _S_try_read_digit(__is, __err);
> if (__digit != -1)
> {
> - __buf.put(_CharT('0') + __digit);
> + __buf.put('0' + __digit);
> __digit = _S_try_read_digit(__is, __err);
> if (__digit != -1)
> - __buf.put(_CharT('0') + __digit);
> + __buf.put('0' + __digit);
> }
>
> auto __i = __is.peek();
> @@ -5009,7 +5009,7 @@ namespace __detail
> {
> __digit = _S_try_read_digit(__is, __err);
> if (__digit != -1)
> - __buf.put(_CharT('0') + __digit);
> + __buf.put('0' + __digit);
> else
> break;
> }
> diff --git a/libstdc++-v3/testsuite/std/time/parse/parse.cc
> b/libstdc++-v3/testsuite/std/time/parse/parse.cc
> index 78c761c115f6..d7c73a1150fc 100644
> --- a/libstdc++-v3/testsuite/std/time/parse/parse.cc
> +++ b/libstdc++-v3/testsuite/std/time/parse/parse.cc
> @@ -317,6 +317,19 @@ test_modifiers()
> VERIFY( s == 12s );
> }
>
> +void
> +test_wchar()
> +{
> + std::wistringstream is;
> + std::chrono::duration<double, std::milli> ms;
> +
> + is.clear();
> + is.str(L"0.125");
> + is >> parse(L"%S", ms);
> + VERIFY( is.good() );
> + VERIFY( ms.count() == 125 );
> +}
> +
> int main()
> {
> test_recommended_practice();
> @@ -324,4 +337,5 @@ int main()
> test_whitespace();
> test_errors();
> test_modifiers();
> + test_wchar();
> }
> --
> 2.52.0
>
>