[libcxx-commits] [libcxx] [libc++][chrono] Applied `[[nodiscard]]` to clocks (PR #174120)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 6 00:51:29 PST 2026


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/174120

>From befcec71f30f4b69ebb9f083add8266010b50cf7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 1 Jan 2026 01:46:33 +0200
Subject: [PATCH 1/4] [libc++][chrono] Applied `[[nodiscard]]` to clocks

In this release:
- [x] `file_clock`
- [x] `steady_clock`
- [x] `system_clock`
- [x] `time_point`

Any other existing clocks are already annotated.

`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html
- https://wg21.link/time.point
- https://wg21.link/time.clock.file
- https://wg21.link/time.clock.steady
- https://wg21.link/time.clock.system

Towards #172124
---
 libcxx/include/__chrono/file_clock.h          |   6 +-
 libcxx/include/__chrono/steady_clock.h        |   2 +-
 libcxx/include/__chrono/system_clock.h        |   6 +-
 libcxx/include/__chrono/time_point.h          |  34 +++--
 .../diagnostics/chrono.nodiscard.verify.cpp   | 124 +++++++++++++++---
 5 files changed, 134 insertions(+), 38 deletions(-)

diff --git a/libcxx/include/__chrono/file_clock.h b/libcxx/include/__chrono/file_clock.h
index 1885f0facce15..968f652f796d2 100644
--- a/libcxx/include/__chrono/file_clock.h
+++ b/libcxx/include/__chrono/file_clock.h
@@ -60,16 +60,18 @@ struct _FilesystemClock {
 
   _LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
 
-  _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
+  [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept;
 
 #  if _LIBCPP_STD_VER >= 20
   template <class _Duration>
+  [[nodiscard]]
   _LIBCPP_HIDE_FROM_ABI static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
     return chrono::sys_time<_Duration>(__t.time_since_epoch());
   }
 
   template <class _Duration>
-  _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration>
+  from_sys(const chrono::sys_time<_Duration>& __t) {
     return chrono::file_time<_Duration>(__t.time_since_epoch());
   }
 #  endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/steady_clock.h b/libcxx/include/__chrono/steady_clock.h
index 1b247b2c28609..8e68c9a3c20f2 100644
--- a/libcxx/include/__chrono/steady_clock.h
+++ b/libcxx/include/__chrono/steady_clock.h
@@ -31,7 +31,7 @@ class _LIBCPP_EXPORTED_FROM_ABI steady_clock {
   typedef chrono::time_point<steady_clock, duration> time_point;
   static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true;
 
-  static time_point now() _NOEXCEPT;
+  [[__nodiscard__]] static time_point now() _NOEXCEPT;
 };
 #endif
 
diff --git a/libcxx/include/__chrono/system_clock.h b/libcxx/include/__chrono/system_clock.h
index 5a9eb65bdae7a..e3ef75ae50fa6 100644
--- a/libcxx/include/__chrono/system_clock.h
+++ b/libcxx/include/__chrono/system_clock.h
@@ -31,9 +31,9 @@ class _LIBCPP_EXPORTED_FROM_ABI system_clock {
   typedef chrono::time_point<system_clock> time_point;
   static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false;
 
-  static time_point now() _NOEXCEPT;
-  static time_t to_time_t(const time_point& __t) _NOEXCEPT;
-  static time_point from_time_t(time_t __t) _NOEXCEPT;
+  [[__nodiscard__]] static time_point now() _NOEXCEPT;
+  [[__nodiscard__]] static time_t to_time_t(const time_point& __t) _NOEXCEPT;
+  [[__nodiscard__]] static time_point from_time_t(time_t __t) _NOEXCEPT;
 };
 
 #if _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index 438f065c1d99d..0dc43a28d6198 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -56,7 +56,9 @@ class time_point {
 
   // observer
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {
+    return __d_;
+  }
 
   // arithmetic
 
@@ -84,8 +86,12 @@ class time_point {
 
   // special values
 
-  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); }
-  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {
+    return time_point(duration::min());
+  }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {
+    return time_point(duration::max());
+  }
 };
 
 } // namespace chrono
@@ -98,29 +104,32 @@ struct common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_C
 namespace chrono {
 
 template <class _ToDuration, class _Clock, class _Duration, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
 time_point_cast(const time_point<_Clock, _Duration>& __t) {
   return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
 }
 
 #if _LIBCPP_STD_VER >= 17
 template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
+[[nodiscard]] inline
+    _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) {
   return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())};
 }
 
 template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> ceil(const time_point<_Clock, _Duration>& __t) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration>
+ceil(const time_point<_Clock, _Duration>& __t) {
   return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())};
 }
 
 template <class _ToDuration, class _Clock, class _Duration, enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> round(const time_point<_Clock, _Duration>& __t) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration>
+round(const time_point<_Clock, _Duration>& __t) {
   return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())};
 }
 
 template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
+[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) {
   return __d >= __d.zero() ? +__d : -__d;
 }
 #endif // _LIBCPP_STD_VER >= 17
@@ -190,7 +199,7 @@ operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock
 // time_point operator+(time_point x, duration y);
 
 template <class _Clock, class _Duration1, class _Rep2, class _Period2>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
 operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
   typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
@@ -200,7 +209,7 @@ operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Pe
 // time_point operator+(duration x, time_point y);
 
 template <class _Rep1, class _Period1, class _Clock, class _Duration2>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
 operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
   return __rhs + __lhs;
@@ -209,7 +218,7 @@ operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Dura
 // time_point operator-(time_point x, duration y);
 
 template <class _Clock, class _Duration1, class _Rep2, class _Period2>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
 operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) {
   typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret;
@@ -219,7 +228,8 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Pe
 // duration operator-(time_point x, time_point y);
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+typename common_type<_Duration1, _Duration2>::type
 operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) {
   return __lhs.time_since_epoch() - __rhs.time_since_epoch();
 }
diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index 700dcc37c34ef..3c4ef6573f2e6 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -6,21 +6,24 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Check that format functions are marked [[nodiscard]] as a conforming extension
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
 // UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+// UNSUPPORTED: no-monotonic-clock
 
 // XFAIL: libcpp-has-no-experimental-tzdb
 // XFAIL: availability-tzdb-missing
 
 // <chrono>
 
+// Check that functions are marked [[nodiscard]]
+
 #include <chrono>
+#include <ctime>
+#include <ratio>
 #include <ratio>
 
 #include "test_macros.h"
 
+#if TEST_STD_VER >= 20
 // These types have "private" constructors.
 void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chrono::leap_second leap) {
   std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
@@ -76,34 +79,72 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro
     t::locate_zone(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
 
-  { // [time.clock.utc]
+  {
+    std::chrono::zoned_time<std::chrono::seconds> zt;
+
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::utc_clock::now();
+    static_cast<std::chrono::sys_seconds>(zt);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    static_cast<std::chrono::local_seconds>(zt);
 
+    zt.get_time_zone();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    zt.get_local_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    zt.get_sys_time();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    zt.get_info();       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  }
+}
+#endif // TEST_STD_VER >= 20
+
+void test() {
+#if TEST_STD_VER >= 20
+  { // [time.clock.file]
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::utc_clock::to_sys(std::chrono::utc_seconds{});
+    std::chrono::file_clock::now();
+
+    using Duration = std::chrono::duration<double, std::ratio<1, 30>>;
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::utc_clock::from_sys(std::chrono::sys_seconds{});
+    std::chrono::file_clock::to_sys(std::chrono::file_time<Duration>{});
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::get_leap_second_info(std::chrono::utc_seconds{});
+    std::chrono::file_clock::from_sys(std::chrono::sys_time<Duration>{});
   }
+#endif
 
-  {
-    std::chrono::zoned_time<std::chrono::seconds> zt;
+#if TEST_STD_VER >= 20
+  { // [time.clock.gps]
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::gps_clock::now();
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    static_cast<std::chrono::sys_seconds>(zt);
+    std::chrono::gps_clock::to_utc(std::chrono::gps_seconds{});
+
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    static_cast<std::chrono::local_seconds>(zt);
+    std::chrono::gps_clock::from_utc(std::chrono::utc_seconds{});
+  }
+#endif // TEST_STD_VER >= 20
 
-    zt.get_time_zone();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    zt.get_local_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    zt.get_sys_time();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    zt.get_info();       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  { // [time.clock.steady]
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::steady_clock::now();
+  }
+
+  { // [time.clock.system]
+
+    std::chrono::time_point<std::chrono::system_clock> tp;
+    std::time_t time = std::time(nullptr);
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::system_clock::now();
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::system_clock::to_time_t(tp);
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::system_clock::from_time_t(time);
   }
 
+#if TEST_STD_VER >= 20
   { // [time.clock.tai]
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     std::chrono::tai_clock::now();
@@ -114,17 +155,60 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     std::chrono::tai_clock::from_utc(std::chrono::utc_seconds{});
   }
+#endif
+
+  { // [time.point]
+    std::chrono::time_point<std::chrono::system_clock> tp;
+    std::chrono::duration<double, std::ratio<1, 30> > dr;
 
-  { // [time.clock.gps]
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::gps_clock::now();
+    tp.time_since_epoch();
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::gps_clock::to_utc(std::chrono::gps_seconds{});
+    tp.min();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    tp.max();
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::gps_clock::from_utc(std::chrono::utc_seconds{});
+    std::chrono::time_point_cast<std::chrono::seconds>(tp);
+
+#if TEST_STD_VER >= 17
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::floor<std::chrono::seconds>(tp);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::ceil<std::chrono::seconds>(tp);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::round<std::chrono::seconds>(tp);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::abs(dr);
+#endif
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    tp + dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr + tp;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    tp - dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    tp - tp;
+  }
+
+#if TEST_STD_VER >= 20
+  { // [time.clock.utc]
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::utc_clock::now();
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::utc_clock::to_sys(std::chrono::utc_seconds{});
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::utc_clock::from_sys(std::chrono::sys_seconds{});
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::get_leap_second_info(std::chrono::utc_seconds{});
   }
+#endif // TEST_STD_VER >= 20
 
   { // [time.duration]
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}

>From 79c32530feaaefcf346ae1da312298482b6f9a18 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 5 Jan 2026 19:21:23 +0200
Subject: [PATCH 2/4] Addressed comments

---
 libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index 3c4ef6573f2e6..4d33525564188 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-// UNSUPPORTED: no-monotonic-clock
 
 // XFAIL: libcpp-has-no-experimental-tzdb
 // XFAIL: availability-tzdb-missing
@@ -124,10 +123,12 @@ void test() {
   }
 #endif // TEST_STD_VER >= 20
 
+#if _LIBCPP_HAS_MONOTONIC_CLOCK
   { // [time.clock.steady]
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     std::chrono::steady_clock::now();
   }
+#endif
 
   { // [time.clock.system]
 

>From 998452e9f02bb345b8d28def077e70e0107b778f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 6 Jan 2026 10:20:52 +0200
Subject: [PATCH 3/4] Refactored after merge

---
 .../diagnostics/chrono.nodiscard.verify.cpp   | 174 +++++++++---------
 1 file changed, 87 insertions(+), 87 deletions(-)

diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index 4d33525564188..168aefc450679 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -95,6 +95,93 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro
 #endif // TEST_STD_VER >= 20
 
 void test() {
+  { // [time.duration]
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::microseconds(2));
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration_values<int>::zero();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration_values<int>::max();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration_values<int>::min();
+
+    std::chrono::duration<int, std::ratio<1, 30> > dr;
+
+#if TEST_STD_VER >= 17
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::floor<std::chrono::seconds>(dr);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::ceil<std::chrono::seconds>(dr);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::round<std::chrono::seconds>(dr);
+#endif
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr.count();
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    +dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    -dr;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration<int, std::ratio<1, 30> >::zero();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration<int, std::ratio<1, 30> >::max();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::chrono::duration<int, std::ratio<1, 30> >::min();
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr + dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr - dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr * 94;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94 * dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr / 82;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr / dr;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr % 47;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    dr % dr;
+
+    using namespace std::chrono_literals;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94h;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    82.5h;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94min;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    82.5min;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94s;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    82.5s;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94ms;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    82.5ms;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94us;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    82.5us;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    94ns;
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    82.5ns;
+  }
+
 #if TEST_STD_VER >= 20
   { // [time.clock.file]
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -210,91 +297,4 @@ void test() {
     std::chrono::get_leap_second_info(std::chrono::utc_seconds{});
   }
 #endif // TEST_STD_VER >= 20
-
-  { // [time.duration]
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::microseconds(2));
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration_values<int>::zero();
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration_values<int>::max();
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration_values<int>::min();
-
-    std::chrono::duration<int, std::ratio<1, 30> > dr;
-
-#if TEST_STD_VER >= 17
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::floor<std::chrono::seconds>(dr);
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::ceil<std::chrono::seconds>(dr);
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::round<std::chrono::seconds>(dr);
-#endif
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr.count();
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    +dr;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    -dr;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration<int, std::ratio<1, 30> >::zero();
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration<int, std::ratio<1, 30> >::max();
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::chrono::duration<int, std::ratio<1, 30> >::min();
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr + dr;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr - dr;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr * 94;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94 * dr;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr / 82;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr / dr;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr % 47;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    dr % dr;
-
-    using namespace std::chrono_literals;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94h;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    82.5h;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94min;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    82.5min;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94s;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    82.5s;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94ms;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    82.5ms;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94us;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    82.5us;
-
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    94ns;
-    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    82.5ns;
-  }
 }

>From bafdb810b746cfca2b96f0f472139875c0b0ee3b Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 6 Jan 2026 10:51:11 +0200
Subject: [PATCH 4/4] Fixed test

---
 libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index 168aefc450679..975e5dc8145dc 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -18,7 +18,6 @@
 #include <chrono>
 #include <ctime>
 #include <ratio>
-#include <ratio>
 
 #include "test_macros.h"
 
@@ -149,6 +148,7 @@ void test() {
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     dr % dr;
 
+#if TEST_STD_VER >= 17
     using namespace std::chrono_literals;
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -180,6 +180,7 @@ void test() {
     94ns;
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     82.5ns;
+#endif // TEST_STD_VER >= 14
   }
 
 #if TEST_STD_VER >= 20



More information about the libcxx-commits mailing list