diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7b9c30e3b642..95ac7c935c4a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,43 @@ +2020-03-25 Jonathan Wakely + + * include/bits/fs_fwd.h (filesystem::__file_clock): Move to ... + * include/std/chrono (filesystem::__file_clock): Here. + (filesystem::__file_clock::from_sys, filesystem::__file_clock::to_sys): + Define public member functions for C++20. + (is_clock, is_clock_v): Define traits for C++20. + * include/std/condition_variable (condition_variable::wait_until): Add + check for valid clock. + * include/std/future (_State_baseV2::wait_until): Likewise. + * include/std/mutex (__timed_mutex_impl::_M_try_lock_until): Likewise. + * include/std/shared_mutex (shared_timed_mutex::try_lock_shared_until): + Likewise. + * include/std/thread (this_thread::sleep_until): Likewise. + * testsuite/30_threads/condition_variable/members/2.cc: Qualify + slow_clock with new namespace. + * testsuite/30_threads/condition_variable/members/clock_neg.cc: New + test. + * testsuite/30_threads/condition_variable_any/members/clock_neg.cc: + New test. + * testsuite/30_threads/future/members/clock_neg.cc: New test. + * testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc: + Qualify slow_clock with new namespace. + * testsuite/30_threads/recursive_timed_mutex/try_lock_until/ + clock_neg.cc: New test. + * testsuite/30_threads/shared_future/members/clock_neg.cc: New + test. + * testsuite/30_threads/shared_lock/locking/clock_neg.cc: New test. + * testsuite/30_threads/shared_timed_mutex/try_lock_until/clock_neg.cc: + New test. + * testsuite/30_threads/timed_mutex/try_lock_until/3.cc: Qualify + slow_clock with new namespace. + * testsuite/30_threads/timed_mutex/try_lock_until/4.cc: Likewise. + * testsuite/30_threads/timed_mutex/try_lock_until/clock_neg.cc: New + test. + * testsuite/30_threads/unique_lock/locking/clock_neg.cc: New test. + * testsuite/std/time/traits/is_clock.cc: New test. + * testsuite/util/slow_clock.h (slow_clock): Move to __gnu_test + namespace. + 2020-03-21 Jonathan Wakely PR libstdc++/93245 diff --git a/libstdc++-v3/include/bits/fs_fwd.h b/libstdc++-v3/include/bits/fs_fwd.h index 1d7495825d6d..6363eca867c2 100644 --- a/libstdc++-v3/include/bits/fs_fwd.h +++ b/libstdc++-v3/include/bits/fs_fwd.h @@ -291,48 +291,6 @@ _GLIBCXX_END_NAMESPACE_CXX11 operator^=(directory_options& __x, directory_options __y) noexcept { return __x = __x ^ __y; } - struct __file_clock - { - using duration = chrono::nanoseconds; - using rep = duration::rep; - using period = duration::period; - using time_point = chrono::time_point<__file_clock>; - static constexpr bool is_steady = false; - - static time_point - now() noexcept - { return _S_from_sys(chrono::system_clock::now()); } - - private: - using __sys_clock = chrono::system_clock; - - // This clock's (unspecified) epoch is 2174-01-01 00:00:00 UTC. - // A signed 64-bit duration with nanosecond resolution gives roughly - // +/- 292 years, which covers the 1901-2446 date range for ext4. - static constexpr chrono::seconds _S_epoch_diff{6437664000}; - - protected: - // For internal use only - template - static - chrono::time_point<__file_clock, _Dur> - _S_from_sys(const chrono::time_point<__sys_clock, _Dur>& __t) noexcept - { - using __file_time = chrono::time_point<__file_clock, _Dur>; - return __file_time{__t.time_since_epoch()} - _S_epoch_diff; - } - - // For internal use only - template - static - chrono::time_point<__sys_clock, _Dur> - _S_to_sys(const chrono::time_point<__file_clock, _Dur>& __t) noexcept - { - using __sys_time = chrono::time_point<__sys_clock, _Dur>; - return __sys_time{__t.time_since_epoch()} + _S_epoch_diff; - } - }; - using file_time_type = __file_clock::time_point; // operational functions diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 477d50854b06..b1fa5b832956 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -41,11 +41,18 @@ #include #include #include // for literals support. +#if __cplusplus > 201703L +# include +#endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __cplusplus >= 201703L + namespace filesystem { struct __file_clock; }; +#endif + /** * @defgroup chrono Time * @ingroup utilities @@ -237,6 +244,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION treat_as_floating_point<_Rep>::value; #endif // C++17 +#if __cplusplus > 201703L + template + struct is_clock; + + template + inline constexpr bool is_clock_v = is_clock<_Tp>::value; + +#if __cpp_lib_concepts + template + struct is_clock : false_type + { }; + + template + requires requires { + typename _Tp::rep; + typename _Tp::period; + typename _Tp::duration; + typename _Tp::time_point::clock; + typename _Tp::time_point::duration; + { &_Tp::is_steady } -> same_as; + { _Tp::now() } -> same_as; + requires same_as>; + requires same_as; + } + struct is_clock<_Tp> : true_type + { }; +#else + template + struct __is_clock_impl : false_type + { }; + + template + struct __is_clock_impl<_Tp, + void_t> + : __and_>, + is_same, + is_same, + is_same>::type + { }; + + template + struct is_clock : __is_clock_impl<_Tp>::type + { }; +#endif +#endif // C++20 + #if __cplusplus >= 201703L # define __cpp_lib_chrono 201611 @@ -948,6 +1009,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using high_resolution_clock = system_clock; } // end inline namespace _V2 + +#if __cplusplus > 201703L + template + using sys_time = time_point; + using sys_seconds = sys_time; + + using file_clock = ::std::filesystem::__file_clock; + + template + using file_time = time_point; + + template<> struct is_clock : true_type { }; + template<> struct is_clock : true_type { }; + template<> struct is_clock : true_type { }; + + template<> inline constexpr bool is_clock_v = true; + template<> inline constexpr bool is_clock_v = true; + template<> inline constexpr bool is_clock_v = true; +#endif // C++20 + // @} } // namespace chrono @@ -1071,6 +1152,67 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using namespace literals::chrono_literals; } // namespace chrono +#if __cplusplus >= 201703L + namespace filesystem + { + struct __file_clock + { + using duration = chrono::nanoseconds; + using rep = duration::rep; + using period = duration::period; + using time_point = chrono::time_point<__file_clock>; + static constexpr bool is_steady = false; + + static time_point + now() noexcept + { return _S_from_sys(chrono::system_clock::now()); } + +#if __cplusplus > 201703L + template + static + chrono::file_time<_Dur> + from_sys(const chrono::sys_time<_Dur>& __t) noexcept + { return _S_from_sys(__t); } + + // For internal use only + template + static + chrono::sys_time<_Dur> + to_sys(const chrono::file_time<_Dur>& __t) noexcept + { return _S_to_sys(__t); } +#endif // C++20 + + private: + using __sys_clock = chrono::system_clock; + + // This clock's (unspecified) epoch is 2174-01-01 00:00:00 UTC. + // A signed 64-bit duration with nanosecond resolution gives roughly + // +/- 292 years, which covers the 1901-2446 date range for ext4. + static constexpr chrono::seconds _S_epoch_diff{6437664000}; + + protected: + // For internal use only + template + static + chrono::time_point<__file_clock, _Dur> + _S_from_sys(const chrono::time_point<__sys_clock, _Dur>& __t) noexcept + { + using __file_time = chrono::time_point<__file_clock, _Dur>; + return __file_time{__t.time_since_epoch()} - _S_epoch_diff; + } + + // For internal use only + template + static + chrono::time_point<__sys_clock, _Dur> + _S_to_sys(const chrono::time_point<__file_clock, _Dur>& __t) noexcept + { + using __sys_time = chrono::time_point<__sys_clock, _Dur>; + return __sys_time{__t.time_since_epoch()} + _S_epoch_diff; + } + }; + } // namespace filesystem +#endif // C++17 #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index 5e98d1b0a6c7..cc7f99f6921d 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -131,6 +131,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION wait_until(unique_lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime) { +#if __cplusplus > 201703L + static_assert(chrono::is_clock_v<_Clock>); +#endif const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 59aa981261b2..97506a27e37c 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -371,6 +371,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs) { +#if __cplusplus > 201703L + static_assert(chrono::is_clock_v<_Clock>); +#endif // First, check if the future has been made ready. Use acquire MO // to synchronize with the thread that made it ready. if (_M_status._M_load(memory_order_acquire) == _Status::__ready) diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index a4a8df07f037..12b7e548d179 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -189,6 +189,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { +#if __cplusplus > 201703L + static_assert(chrono::is_clock_v<_Clock>); +#endif // The user-supplied clock may not tick at the same rate as // steady_clock, so we must loop in order to guarantee that // the timeout has expired before returning false. diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex index 9b597e762998..414dce3a1b75 100644 --- a/libstdc++-v3/include/std/shared_mutex +++ b/libstdc++-v3/include/std/shared_mutex @@ -554,6 +554,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { +#if __cplusplus > 201703L + static_assert(chrono::is_clock_v<_Clock>); +#endif // The user-supplied clock may not tick at the same rate as // steady_clock, so we must loop in order to guarantee that // the timeout has expired before returning false. @@ -639,6 +642,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __atime) { +#if __cplusplus > 201703L + static_assert(chrono::is_clock_v<_Clock>); +#endif // The user-supplied clock may not tick at the same rate as // steady_clock, so we must loop in order to guarantee that // the timeout has expired before returning false. diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 1f9c13ff7d1a..e1bba0cb29b3 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -414,6 +414,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline void sleep_until(const chrono::time_point<_Clock, _Duration>& __atime) { +#if __cplusplus > 201703L + static_assert(chrono::is_clock_v<_Clock>); +#endif auto __now = _Clock::now(); if (_Clock::is_steady) { diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc index baa10375cf9c..c671804b4064 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc @@ -55,6 +55,8 @@ void test01() void test01_alternate_clock() { + using __gnu_test::slow_clock; + try { std::condition_variable c1; diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/clock_neg.cc new file mode 100644 index 000000000000..11b540f58c89 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/clock_neg.cc @@ -0,0 +1,61 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::mutex m; + std::unique_lock l(m); + std::condition_variable cv; + cv.wait_until(l, clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::mutex m; + std::unique_lock l(m); + std::condition_variable cv; + cv.wait_until(l, cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/clock_neg.cc new file mode 100644 index 000000000000..4302363f407f --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/clock_neg.cc @@ -0,0 +1,61 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::mutex m; + std::unique_lock l(m); + std::condition_variable_any cv; + cv.wait_until(l, clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::mutex m; + std::unique_lock l(m); + std::condition_variable_any cv; + cv.wait_until(l, cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/future/members/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/future/members/clock_neg.cc new file mode 100644 index 000000000000..a94d770fb62f --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/future/members/clock_neg.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::promise p; + std::future f = p.get_future(); + f.wait_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::promise p; + std::future f = p.get_future(); + f.wait_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc index b85381de46c5..120655ceb650 100644 --- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc +++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc @@ -72,5 +72,5 @@ int main() { test(); test(); - test(); + test<__gnu_test::slow_clock>(); } diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/clock_neg.cc new file mode 100644 index 000000000000..499e6675545c --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/clock_neg.cc @@ -0,0 +1,57 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::recursive_timed_mutex m; + m.try_lock_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::recursive_timed_mutex m; + m.try_lock_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/members/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_future/members/clock_neg.cc new file mode 100644 index 000000000000..59f63cc1cf47 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/shared_future/members/clock_neg.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::promise p; + std::shared_future f = p.get_future(); + f.wait_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::promise p; + std::shared_future f = p.get_future(); + f.wait_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/clock_neg.cc new file mode 100644 index 000000000000..9a21a88ed600 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/clock_neg.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::shared_timed_mutex m; + std::shared_lock l(m, std::defer_lock); + l.try_lock_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::shared_timed_mutex m; + std::shared_lock l(m, std::defer_lock); + l.try_lock_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/clock_neg.cc new file mode 100644 index 000000000000..23d4b9d9bbfa --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/clock_neg.cc @@ -0,0 +1,57 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::shared_timed_mutex m; + m.try_lock_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::shared_timed_mutex m; + m.try_lock_shared_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc index 32c84ef62868..ed5a6b0b8b7f 100644 --- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc +++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc @@ -72,5 +72,5 @@ int main() { test(); test(); - test(); + test<__gnu_test::slow_clock>(); } diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/4.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/4.cc index 037e4086f975..a7a77d2294d4 100644 --- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/4.cc +++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/4.cc @@ -64,5 +64,5 @@ int main() { test(); test(); - test(); + test<__gnu_test::slow_clock>(); } diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/clock_neg.cc new file mode 100644 index 000000000000..a9c0132d99b6 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/clock_neg.cc @@ -0,0 +1,57 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::timed_mutex m; + m.try_lock_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::timed_mutex m; + m.try_lock_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/locking/clock_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/locking/clock_neg.cc new file mode 100644 index 000000000000..c7ac9cdc466b --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/unique_lock/locking/clock_neg.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +struct clok +{ + // no clok::rep or clok::period defined + using duration = std::chrono::milliseconds; + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test01() +{ + std::timed_mutex m; + std::unique_lock l(m, std::defer_lock); + l.try_lock_until(clok::now()); // { dg-error "here" } +} + +struct cloc +{ + using duration = std::chrono::milliseconds; + using rep = duration::rep; + using period = duration::period; + // cloc::time_point::duration should be the same as cloc::duration: + using time_point = std::chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +void +test02() +{ + std::recursive_timed_mutex m; + std::unique_lock l(m, std::defer_lock); + l.try_lock_until(cloc::now()); // { dg-error "here" } +} + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/std/time/traits/is_clock.cc b/libstdc++-v3/testsuite/std/time/traits/is_clock.cc new file mode 100644 index 000000000000..85f118253c37 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/traits/is_clock.cc @@ -0,0 +1,124 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include +#include + +namespace chrono = std::chrono; + +static_assert( chrono::is_clock::value ); +static_assert( chrono::is_clock_v ); + +static_assert( chrono::is_clock::value ); +static_assert( chrono::is_clock_v ); + +static_assert( chrono::is_clock::value ); +static_assert( chrono::is_clock_v ); + +static_assert(chrono::is_clock::value); +static_assert(chrono::is_clock_v); + +static_assert( chrono::is_clock<__gnu_test::slow_clock>::value ); +static_assert( chrono::is_clock_v<__gnu_test::slow_clock> ); + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +struct not_a_clock_1 +{ + using rep = int; + using period = std::ratio<4, 2>; + using duration = chrono::duration; // different rep + using time_point = chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +struct not_a_clock_2 +{ + using rep = int; + using period = int; // not a std::ratio + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +struct not_a_clock_3 +{ + using rep = int; + using period = std::ratio<1>; + using duration = chrono::duration; + // wrong duration: + using time_point = chrono::time_point>; + static constexpr bool is_steady = false; + static time_point now(); +}; + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +struct not_a_clock_4 +{ + using rep = int; + using period = std::ratio<1>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr int is_steady = 0; // not a const bool + static time_point now(); +}; + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +struct not_a_clock_5 +{ + using rep = int; + using period = std::ratio<1>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = false; + static int now(); // wrong return type +}; + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); + +struct not_a_clock_6 +{ + using rep = int; + using period = std::ratio<1>; + using duration = chrono::duration; + using time_point = chrono::time_point; + const bool is_steady = false; // not static + static time_point now(); +}; + +static_assert( ! chrono::is_clock::value ); +static_assert( ! chrono::is_clock_v ); diff --git a/libstdc++-v3/testsuite/util/slow_clock.h b/libstdc++-v3/testsuite/util/slow_clock.h index bae734f76c84..d1f4bbba8514 100644 --- a/libstdc++-v3/testsuite/util/slow_clock.h +++ b/libstdc++-v3/testsuite/util/slow_clock.h @@ -22,6 +22,8 @@ #include +namespace __gnu_test +{ struct slow_clock { using rep = std::chrono::system_clock::rep; @@ -36,3 +38,4 @@ struct slow_clock return time_point{real.time_since_epoch() / 3}; } }; +}