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
>
>

Reply via email to