Fix a UB in chrono
This commit is contained in:
parent
c06bef7273
commit
d9f045fba1
@ -1663,7 +1663,7 @@ struct chrono_formatter {
|
|||||||
out = format_decimal<char_type>(out, n, num_digits).end;
|
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 =
|
constexpr auto num_fractional_digits =
|
||||||
count_fractional_digits(Duration::period::num, Duration::period::den);
|
count_fractional_digits(Duration::period::num, Duration::period::den);
|
||||||
|
|
||||||
@ -1770,8 +1770,22 @@ struct chrono_formatter {
|
|||||||
if (handle_nan_inf()) return;
|
if (handle_nan_inf()) return;
|
||||||
|
|
||||||
if (ns == numeric_system::standard) {
|
if (ns == numeric_system::standard) {
|
||||||
|
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(second(), 2);
|
||||||
write_fractional_seconds(std::chrono::duration<rep, Period>{val});
|
write_fractional_seconds(std::chrono::duration<rep, Period>(val));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto time = tm();
|
auto time = tm();
|
||||||
|
@ -557,6 +557,9 @@ TEST(chrono_test, special_durations) {
|
|||||||
"03:33");
|
"03:33");
|
||||||
EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}),
|
EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}),
|
||||||
"03:33:20");
|
"03:33:20");
|
||||||
|
EXPECT_EQ("44.000000000000",
|
||||||
|
fmt::format("{:%S}", std::chrono::duration<float, std::pico>(
|
||||||
|
1.54213895E+26)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(chrono_test, unsigned_duration) {
|
TEST(chrono_test, unsigned_duration) {
|
||||||
|
Loading…
Reference in New Issue
Block a user