Commit d9f045fb authored by Victor Zverovich's avatar Victor Zverovich

Fix a UB in chrono

parent c06bef72
......@@ -1663,7 +1663,7 @@ struct chrono_formatter {
out = format_decimal<char_type>(out, n, num_digits).end;
}
template <class Duration> void write_fractional_seconds(Duration d) {
template <typename Duration> void write_fractional_seconds(Duration d) {
constexpr auto num_fractional_digits =
count_fractional_digits(Duration::period::num, Duration::period::den);
......@@ -1770,8 +1770,22 @@ struct chrono_formatter {
if (handle_nan_inf()) return;
if (ns == numeric_system::standard) {
write(second(), 2);
write_fractional_seconds(std::chrono::duration<rep, Period>{val});
if (std::is_floating_point<rep>::value) {
auto num_fractional_digits =
count_fractional_digits(Period::num, Period::den);
auto buf = memory_buffer();
format_to(std::back_inserter(buf), runtime("{:.{}f}"),
std::fmod(val * static_cast<rep>(Period::num) /
static_cast<rep>(Period::den),
60),
num_fractional_digits);
if (negative) *out++ = '-';
if (buf.size() < 2 || buf[1] == '.') *out++ = '0';
out = std::copy(buf.begin(), buf.end(), out);
} else {
write(second(), 2);
write_fractional_seconds(std::chrono::duration<rep, Period>(val));
}
return;
}
auto time = tm();
......
......@@ -557,6 +557,9 @@ TEST(chrono_test, special_durations) {
"03:33");
EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}),
"03:33:20");
EXPECT_EQ("44.000000000000",
fmt::format("{:%S}", std::chrono::duration<float, std::pico>(
1.54213895E+26)));
}
TEST(chrono_test, unsigned_duration) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment