libstdc++: Fix formatting of most negative chrono::duration [PR116755]
When formatting chrono::duration<signed-integer-type, P>::min() we were causing undefined behaviour by trying to form the negative of the most negative value. If we convert negative durations with integer rep to the corresponding unsigned integer rep then we can safely represent all values. libstdc++-v3/ChangeLog: PR libstdc++/116755 * include/bits/chrono_io.h (formatter<duration<R,P>>::format): Cast negative integral durations to unsigned rep. * testsuite/20_util/duration/io.cc: Test the most negative integer durations.
This commit is contained in:
parent
b6463161c3
commit
482e651f57
2 changed files with 22 additions and 2 deletions
|
@ -1720,8 +1720,20 @@ namespace __format
|
|||
basic_format_context<_Out, _CharT>& __fc) const
|
||||
{
|
||||
if constexpr (numeric_limits<_Rep>::is_signed)
|
||||
if (__d < __d.zero())
|
||||
return _M_f._M_format(-__d, __fc, true);
|
||||
if (__d < __d.zero()) [[unlikely]]
|
||||
{
|
||||
if constexpr (is_integral_v<_Rep>)
|
||||
{
|
||||
// -d is undefined for the most negative integer.
|
||||
// Convert duration to corresponding unsigned rep.
|
||||
using _URep = make_unsigned_t<_Rep>;
|
||||
auto __ucnt = -static_cast<_URep>(__d.count());
|
||||
auto __ud = chrono::duration<_URep, _Period>(__ucnt);
|
||||
return _M_f._M_format(__ud, __fc, true);
|
||||
}
|
||||
else
|
||||
return _M_f._M_format(-__d, __fc, true);
|
||||
}
|
||||
return _M_f._M_format(__d, __fc, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,14 @@ test_format()
|
|||
VERIFY( s == "500ms" );
|
||||
s = std::format("{:%Q %q}", u);
|
||||
VERIFY( s == "500 ms" );
|
||||
|
||||
// PR libstdc++/116755 extra minus sign for most negative value
|
||||
auto minsec = std::chrono::seconds::min();
|
||||
s = std::format("{}", minsec);
|
||||
auto expected = std::format("{}s", minsec.count());
|
||||
VERIFY( s == expected );
|
||||
s = std::format("{:%Q%q}", minsec);
|
||||
VERIFY( s == expected );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Reference in a new issue