[libcxx-commits] [libcxx] [libc++][chrono] Fix years/months periods on GCC/i386 (PR #223669)
Leonidas Spyropoulos via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Sep 25 23:00:01 PDT 2026
https://github.com/inglor updated https://github.com/llvm/llvm-project/pull/223669
>From f6d727ba9491bc20369fab899d2a9c2155f8f293 Mon Sep 17 00:00:00 2001
From: Leonidas Spyropoulos <artafinde at archlinux.org>
Date: Tue, 15 Sep 2026 12:40:16 +0100
Subject: [PATCH] [libc++][chrono] Fix years/months periods on GCC/i386
`static_cast<int>(365.2425 * 60 * 60 * 24)`, added in #178182, isn't
exactly 31556952 on every host: GCC targeting i386 folds it in x87
extended precision and gets 31556951, making `years::period` and
`months::period` coprime and breaking `year_month` arithmetic. Use the
literal values instead, there's no readability to lose since they were
only there to avoid a template instantiation in the first place.
Fixes #223223
Signed-off-by: Leonidas Spyropoulos <artafinde at archlinux.org>
---
libcxx/include/__chrono/duration.h | 4 ++--
libcxx/test/std/time/months.pass.cpp | 3 ++-
libcxx/test/std/time/years.pass.cpp | 3 ++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index fe5bbd07f6d89b..7b6c11adae86b0 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -298,8 +298,8 @@ typedef duration<long, ratio<60 * 60> > hours;
#if _LIBCPP_STD_VER >= 20
typedef duration<int, ratio<60 * 60 * 24>> days;
typedef duration<int, ratio<60 * 60 * 24 * 7>> weeks;
-typedef duration<int, ratio<static_cast<int>(365.2425 * 60 * 60 * 24)>> years;
-typedef duration<int, ratio<static_cast<int>(365.2425 * 60 * 60 * 24) / 12>> months;
+typedef duration<int, ratio<31556952>> years; // 365.2425 * 60 * 60 * 24
+typedef duration<int, ratio<2629746>> months; // years / 12
#endif
// Duration ==
diff --git a/libcxx/test/std/time/months.pass.cpp b/libcxx/test/std/time/months.pass.cpp
index f9c82286bac33e..388b128062ae4d 100644
--- a/libcxx/test/std/time/months.pass.cpp
+++ b/libcxx/test/std/time/months.pass.cpp
@@ -27,6 +27,7 @@ int main(int, char**)
static_assert(std::is_integral<Rep>::value, "");
static_assert(std::numeric_limits<Rep>::digits >= 20, "");
static_assert(std::is_same_v<Period, std::ratio_divide<std::chrono::years::period, std::ratio<12>>>, "");
+ static_assert(Period::num == 2629746 && Period::den == 1, "");
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/time/years.pass.cpp b/libcxx/test/std/time/years.pass.cpp
index ab8b61b200099b..075726d2c0c339 100644
--- a/libcxx/test/std/time/years.pass.cpp
+++ b/libcxx/test/std/time/years.pass.cpp
@@ -27,6 +27,7 @@ int main(int, char**)
static_assert(std::is_integral<Rep>::value, "");
static_assert(std::numeric_limits<Rep>::digits >= 17, "");
static_assert(std::is_same_v<Period, std::ratio_multiply<std::ratio<146097, 400>, std::chrono::days::period>>, "");
+ static_assert(Period::num == 31556952 && Period::den == 1, "");
- return 0;
+ return 0;
}
More information about the libcxx-commits
mailing list