[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