[libcxx-commits] [libcxx] 14df65f - [libc++][chrono] Fix years/months periods on GCC/i386 (#223669)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Sep 27 08:19:34 PDT 2026


Author: Leonidas Spyropoulos
Date: 2026-09-27T23:19:27+08:00
New Revision: 14df65f5db67d0096ef2360abb1e30891dae66b5

URL: https://github.com/llvm/llvm-project/commit/14df65f5db67d0096ef2360abb1e30891dae66b5
DIFF: https://github.com/llvm/llvm-project/commit/14df65f5db67d0096ef2360abb1e30891dae66b5.diff

LOG: [libc++][chrono] Fix years/months periods on GCC/i386 (#223669)

`static_cast<int>(365.2425 * 60 * 60 * 24)`, added in
f537b4e51822b19780386e0575ff95e82f8ec445, 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.

Signed-off-by: Leonidas Spyropoulos <artafinde at archlinux.org>

Added: 
    

Modified: 
    libcxx/include/__chrono/duration.h
    libcxx/test/std/time/months.pass.cpp
    libcxx/test/std/time/years.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index fe5bbd07f6d89..7b6c11adae86b 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 f9c82286bac33..388b128062ae4 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 ab8b61b200099..075726d2c0c33 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