diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index e4bc1ce4fd45..46590074b823 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -934,10 +934,9 @@ inline auto to_nonnegative_int(T value, Int upper) -> Int { } template ::value)> inline auto to_nonnegative_int(T value, Int upper) -> Int { - auto int_value = static_cast(value); - if (int_value < 0 || value > static_cast(upper)) + if (value < 0 || value >= static_cast(upper) + 1) FMT_THROW(format_error("invalid value")); - return int_value; + return static_cast(value); } constexpr auto pow10(std::uint32_t n) -> long long { diff --git a/test/chrono-test.cc b/test/chrono-test.cc index a915359807c1..b7a4e59a8d72 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -989,6 +989,9 @@ TEST(chrono_test, glibc_extensions) { TEST(chrono_test, out_of_range) { auto d = std::chrono::duration(538976288); EXPECT_THROW((void)fmt::format("{:%j}", d), fmt::format_error); + // A floating-point day count that doesn't fit in int. + auto fd = std::chrono::duration(1e300); + EXPECT_THROW((void)fmt::format("{:%j}", fd), fmt::format_error); } TEST(chrono_test, year_month_day) {