diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h index 8b8877aa9a17..9313fc797ecd 100644 --- a/libcxx/include/__chrono/duration.h +++ b/libcxx/include/__chrono/duration.h @@ -556,7 +556,7 @@ using namespace literals::chrono_literals; template requires __has_enabled_hash<_Rep>::value struct hash> { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::duration<_Rep, _Period>& __d) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::duration<_Rep, _Period>& __d) { return hash<_Rep>{}(__d.count()); } }; diff --git a/libcxx/include/__chrono/file_clock.h b/libcxx/include/__chrono/file_clock.h index 1885f0facce1..968f652f796d 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 + [[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 - _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/leap_second.h b/libcxx/include/__chrono/leap_second.h index 665056e5a963..9e9df6b5950a 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -128,7 +128,7 @@ private: template <> struct hash { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::leap_second& __lp) noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::leap_second& __lp) noexcept { return std::__hash_combine(hash{}(__lp.date()), hash{}(__lp.value())); } }; diff --git a/libcxx/include/__chrono/steady_clock.h b/libcxx/include/__chrono/steady_clock.h index 1b247b2c2860..8e68c9a3c20f 100644 --- a/libcxx/include/__chrono/steady_clock.h +++ b/libcxx/include/__chrono/steady_clock.h @@ -31,7 +31,7 @@ public: typedef chrono::time_point 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 5a9eb65bdae7..e3ef75ae50fa 100644 --- a/libcxx/include/__chrono/system_clock.h +++ b/libcxx/include/__chrono/system_clock.h @@ -31,9 +31,9 @@ public: typedef chrono::time_point 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 438f065c1d99..d393e34cdbc4 100644 --- a/libcxx/include/__chrono/time_point.h +++ b/libcxx/include/__chrono/time_point.h @@ -56,7 +56,9 @@ public: // 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 @@ public: // 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<_C namespace chrono { template , 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 , 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 , 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 , 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 ::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 -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 -inline _LIBCPP_HIDE_FROM_ABI +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type, _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 -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 -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(); } @@ -231,7 +241,7 @@ operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, template requires __has_enabled_hash<_Duration>::value struct hash> { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::time_point<_Clock, _Duration>& __tp) { return hash<_Duration>{}(__tp.time_since_epoch()); } }; diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h index b8d33bb7f3ac..e63528e57d1c 100644 --- a/libcxx/include/__chrono/zoned_time.h +++ b/libcxx/include/__chrono/zoned_time.h @@ -223,7 +223,8 @@ operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_ template requires __has_enabled_hash<_Duration>::value && __has_enabled_hash<_TimeZonePtr>::value struct hash> { - _LIBCPP_HIDE_FROM_ABI static size_t operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static size_t + operator()(const chrono::zoned_time<_Duration, _TimeZonePtr>& __zt) { return std::__hash_combine( hash>{}(__zt.get_sys_time()), hash<_TimeZonePtr>{}(__zt.get_time_zone())); } diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp index 700dcc37c34e..94be9679bde7 100644 --- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp @@ -6,9 +6,6 @@ // //===----------------------------------------------------------------------===// -// 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 // XFAIL: libcpp-has-no-experimental-tzdb @@ -16,11 +13,15 @@ // +// Check that functions are marked [[nodiscard]] + #include +#include #include #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(); @@ -68,6 +69,13 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro { leap.date(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} leap.value(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +# if TEST_STD_VER >= 26 + std::hash hash; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + hash(leap); +# endif } { @@ -76,20 +84,6 @@ 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] - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::utc_clock::now(); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::utc_clock::to_sys(std::chrono::utc_seconds{}); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::utc_clock::from_sys(std::chrono::sys_seconds{}); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::get_leap_second_info(std::chrono::utc_seconds{}); - } - { std::chrono::zoned_time zt; @@ -102,30 +96,18 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro 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}} + +# if TEST_STD_VER >= 26 + std::hash> hash; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + hash(zt); +# endif } +} +#endif // TEST_STD_VER >= 20 - { // [time.clock.tai] - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::tai_clock::now(); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::tai_clock::to_utc(std::chrono::tai_seconds{}); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::tai_clock::from_utc(std::chrono::utc_seconds{}); - } - - { // [time.clock.gps] - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::gps_clock::now(); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::gps_clock::to_utc(std::chrono::gps_seconds{}); - - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::chrono::gps_clock::from_utc(std::chrono::utc_seconds{}); - } - +void test() { { // [time.duration] // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::chrono::duration_cast(std::chrono::microseconds(2)); @@ -180,6 +162,7 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} dr % dr; +#if TEST_STD_VER >= 17 using namespace std::chrono_literals; // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} @@ -211,5 +194,136 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro 94ns; // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} 82.5ns; +#endif // TEST_STD_VER >= 14 + +#if TEST_STD_VER >= 26 + std::hash>> hash; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + hash(dr); +#endif } + +#if TEST_STD_VER >= 20 + { // [time.clock.file] + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::file_clock::now(); + + using Duration = std::chrono::duration>; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::file_clock::to_sys(std::chrono::file_time{}); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::file_clock::from_sys(std::chrono::sys_time{}); + } +#endif + +#if TEST_STD_VER >= 20 + { // [time.clock.gps] + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::gps_clock::now(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::gps_clock::to_utc(std::chrono::gps_seconds{}); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::gps_clock::from_utc(std::chrono::utc_seconds{}); + } +#endif // TEST_STD_VER >= 20 + +#if _LIBCPP_HAS_MONOTONIC_CLOCK + { // [time.clock.steady] + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::steady_clock::now(); + } +#endif + + { // [time.clock.system] + + std::chrono::time_point tp; + std::time_t time = std::time(nullptr); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::system_clock::now(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::system_clock::to_time_t(tp); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::system_clock::from_time_t(time); + +#if TEST_STD_VER >= 26 + std::hash> hash; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + hash(tp); +#endif + } + +#if TEST_STD_VER >= 20 + { // [time.clock.tai] + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::tai_clock::now(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::tai_clock::to_utc(std::chrono::tai_seconds{}); + + // expected-warning@+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 tp; + std::chrono::duration > dr; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + tp.time_since_epoch(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + tp.min(); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + tp.max(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::time_point_cast(tp); + +#if TEST_STD_VER >= 17 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::floor(tp); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::ceil(tp); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::round(tp); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::abs(dr); +#endif + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + tp + dr; + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + dr + tp; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + tp - dr; + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + tp - tp; + } + +#if TEST_STD_VER >= 20 + { // [time.clock.utc] + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::utc_clock::now(); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::utc_clock::to_sys(std::chrono::utc_seconds{}); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::chrono::utc_clock::from_sys(std::chrono::sys_seconds{}); + + // expected-warning@+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 }