aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-06-26 20:22:54 +0100
committerJonathan Wakely <jwakely@redhat.com>2024-06-28 10:44:00 +0100
commitd5e352addf4c17d28bcada42409881089c5d8088 (patch)
tree96624cb6a12f58032396dbd0669e152427a96cec
parentef8b60dd48faeaf2b4e28c35401fa10d2a3e53fb (diff)
downloadgcc-d5e352addf4c17d28bcada42409881089c5d8088.zip
gcc-d5e352addf4c17d28bcada42409881089c5d8088.tar.gz
gcc-d5e352addf4c17d28bcada42409881089c5d8088.tar.bz2
libstdc++: Fix std::format for chrono::duration with unsigned rep [PR115668]
Using std::chrono::abs is only valid if numeric_limits<rep>::is_signed is true, so using it unconditionally made it ill-formed to format a duration with an unsigned rep. The duration formatter might as well negate the duration itself instead of using chrono::abs, because it already needs to check for a negative value. libstdc++-v3/ChangeLog: PR libstdc++/115668 * include/bits/chrono_io.h (formatter<duration<R,P, C>::format): Do not use chrono::abs. * testsuite/20_util/duration/io.cc: Check formatting a duration with unsigned rep. (cherry picked from commit dafa750c8a6f0a088677871bfaad054881737ab1)
-rw-r--r--libstdc++-v3/include/bits/chrono_io.h5
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/io.cc6
2 files changed, 10 insertions, 1 deletions
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 3b34992..72c66a0 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -1607,7 +1607,10 @@ namespace __format
format(const chrono::duration<_Rep, _Period>& __d,
basic_format_context<_Out, _CharT>& __fc) const
{
- return _M_f._M_format(chrono::abs(__d), __fc, __d < __d.zero());
+ if constexpr (numeric_limits<_Rep>::is_signed)
+ if (__d < __d.zero())
+ return _M_f._M_format(-__d, __fc, true);
+ return _M_f._M_format(__d, __fc, false);
}
private:
diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc b/libstdc++-v3/testsuite/20_util/duration/io.cc
index 2f940ef..6b00689 100644
--- a/libstdc++-v3/testsuite/20_util/duration/io.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/io.cc
@@ -100,6 +100,12 @@ test_format()
std::chrono::duration<float, std::milli> d{0.5};
s = std::format("{}", d);
VERIFY( s == "0.5ms" );
+
+ std::chrono::duration<unsigned, std::milli> u{500}; // PR libstdc++/115668
+ s = std::format("{}", u);
+ VERIFY( s == "500ms" );
+ s = std::format("{:%Q %q}", u);
+ VERIFY( s == "500 ms" );
}
void