https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111163
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- With this patch: --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -507,6 +507,16 @@ namespace __format if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) __is_neg = __t.is_negative(); + if constexpr (chrono::__is_duration_v<_Tp>) + if constexpr (_Tp::period::num != 1) + { + // Check conversion to seconds will not overflow. + chrono::seconds::rep __s{}; + if (__builtin_mul_overflow(__t.count(), _Tp::period::num, &__s)) + __throw_format_error("chrono format error: integer overflow " + "converting duration to seconds"); + } + auto __print_sign = [&__is_neg, &__out] { if constexpr (chrono::__is_duration_v<_Tp> || __is_specialization_of<_Tp, chrono::hh_mm_ss>) The testcase throws: terminate called after throwing an instance of 'std::format_error' what(): chrono format error: integer overflow converting duration to seconds Aborted (core dumped) This isn't ideal as there are some uses that wouldn't overflow, e.g. std::format("{:%j}", std::chrono::days::max()) This doesn't require any conversion and so could be formatted. But I'm not sure I care about this case, it's pretty unlikely to ever be needed. If we did the overflow checks at the point of conversion then we'd be doing them multiple times for a format string like "%H:%M:%S". But then I suppose we're already converting the duration to hh_mm_ss three times there anyway. The patch in PR 110739 comment 2 would help with that, as the _S_hms call might be subject to common subexpression elimination, and the checks would only be done once. We could also just call _S_hms once up-front when we have a type that can make use of it, and then reuse the result as needed. And the patch above doesn't handle all cases anyway, because this will still overflow: std::format("{:%S}", std::chrono::sys_days{std::chrono::days::max()}); So maybe we just need a checked duration_cast<days>, floor<days>, floor<weeks>, and the check for conversion to seconds for use with hh_mm_ss.