[committed] libstdc++: Add nodiscard in
Tested aarch64-linux and x86_64-linux. Pushed to trunk. I forgot to update the commit log to remove the speculation, because Stephan Lavavej confirmed that MSVC doesn't mark those functions nodiscard because it would result in too many false positives. Although it might find some real bugs, it would also warn about a lot of perfectly correct code. -- >8 -- Add the [[nodiscard]] attribute to several functions in . These all have no side effects and are only called for their return value (e.g. std::count) or produce a result that must not be discarded for correctness (e.g. std::remove). I was intending to add the attribute to a number of other functions like std::copy_if, std::unique_copy, std::set_union, and std::set_difference. I stopped when I noticed that MSVC doesn't use it on those functions, which I suspect is because they're often used with an insert iterator (e.g. std::back_insert_iterator). In that case it doesn't matter if you discard the result, because you have the container to tell you how many elements were copied to the output range. libstdc++-v3/ChangeLog: * include/bits/stl_algo.h (find_end, all_of, none_of, any_of) (find_if_not, is_partitioned, partition_point, remove) (remove_if, unique, lower_bound, upper_bound, equal_range) (binary_search, includes, is_sorted, is_sorted_until, minmax) (minmax_element, is_permutation, clamp, find_if, find_first_of) (adjacent_find, count, count_if, search, search_n, min_element) (max_element): Add nodiscard attribute. * include/bits/stl_algobase.h (min, max, lower_bound, equal) (lexicographical_compare, lexicographical_compare_three_way) (mismatch): Likewise. * include/bits/stl_heap.h (is_heap, is_heap_until): Likewise. * testsuite/25_algorithms/equal/debug/1_neg.cc: Add dg-warning. * testsuite/25_algorithms/equal/debug/2_neg.cc: Likewise. * testsuite/25_algorithms/equal/debug/3_neg.cc: Likewise. * testsuite/25_algorithms/find_first_of/concept_check_1.cc: Likewise. * testsuite/25_algorithms/is_permutation/2.cc: Likewise. * testsuite/25_algorithms/lexicographical_compare/71545.cc: Likewise. * testsuite/25_algorithms/lower_bound/33613.cc: Likewise. * testsuite/25_algorithms/lower_bound/debug/irreflexive.cc: Likewise. * testsuite/25_algorithms/lower_bound/debug/partitioned_neg.cc: Likewise. * testsuite/25_algorithms/lower_bound/debug/partitioned_pred_neg.cc: Likewise. * testsuite/25_algorithms/minmax/3.cc: Likewise. * testsuite/25_algorithms/search/78346.cc: Likewise. * testsuite/25_algorithms/search_n/58358.cc: Likewise. * testsuite/25_algorithms/unique/1.cc: Likewise. * testsuite/25_algorithms/unique/11480.cc: Likewise. * testsuite/25_algorithms/upper_bound/33613.cc: Likewise. * testsuite/25_algorithms/upper_bound/debug/partitioned_neg.cc: Likewise. * testsuite/25_algorithms/upper_bound/debug/partitioned_pred_neg.cc: Likewise. * testsuite/ext/concept_checks.cc: Likewise. * testsuite/ext/is_heap/47709.cc: Likewise. * testsuite/ext/is_sorted/cxx0x.cc: Likewise. --- libstdc++-v3/include/bits/stl_algo.h | 102 +- libstdc++-v3/include/bits/stl_algobase.h | 32 +++--- libstdc++-v3/include/bits/stl_heap.h | 8 +- .../25_algorithms/equal/debug/1_neg.cc| 1 + .../25_algorithms/equal/debug/2_neg.cc| 1 + .../25_algorithms/equal/debug/3_neg.cc| 1 + .../find_first_of/concept_check_1.cc | 1 + .../25_algorithms/is_permutation/2.cc | 1 + .../lexicographical_compare/71545.cc | 1 + .../25_algorithms/lower_bound/33613.cc| 1 + .../lower_bound/debug/irreflexive.cc | 1 + .../lower_bound/debug/partitioned_neg.cc | 1 + .../lower_bound/debug/partitioned_pred_neg.cc | 1 + .../testsuite/25_algorithms/minmax/3.cc | 1 + .../testsuite/25_algorithms/search/78346.cc | 1 + .../testsuite/25_algorithms/search_n/58358.cc | 1 + .../testsuite/25_algorithms/unique/1.cc | 1 + .../testsuite/25_algorithms/unique/11480.cc | 2 +- .../25_algorithms/upper_bound/33613.cc| 1 + .../upper_bound/debug/partitioned_neg.cc | 1 + .../upper_bound/debug/partitioned_pred_neg.cc | 1 + libstdc++-v3/testsuite/ext/concept_checks.cc | 4 + libstdc++-v3/testsuite/ext/is_heap/47709.cc | 1 + libstdc++-v3/testsuite/ext/is_sorted/cxx0x.cc | 1 + 24 files changed, 95 insertions(+), 72 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 7a0cf6b6737..1a996aa61da 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -320,7 +320,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * [__first1,__last1-(__last2-__first2))
[committed] libstdc++: Add [[nodiscard]] to std::span members
Tested x86_64-linux. Pushed to trunk. -- >8 -- All std::span member functions are pure functions that have no side effects. They are only useful for their return value, so they should all warn if that value is not used. libstdc++-v3/ChangeLog: * include/std/span (span, as_bytes, as_writable_bytes): Add [[nodiscard]] attribute on all non-void functions. * testsuite/23_containers/span/back_assert_neg.cc: Suppress nodiscard warning. * testsuite/23_containers/span/back_neg.cc: Likewise. * testsuite/23_containers/span/first_2_assert_neg.cc: Likewise. * testsuite/23_containers/span/first_assert_neg.cc: Likewise. * testsuite/23_containers/span/first_neg.cc: Likewise. * testsuite/23_containers/span/front_assert_neg.cc: Likewise. * testsuite/23_containers/span/front_neg.cc: Likewise. * testsuite/23_containers/span/index_op_assert_neg.cc: Likewise. * testsuite/23_containers/span/index_op_neg.cc: Likewise. * testsuite/23_containers/span/last_2_assert_neg.cc: Likewise. * testsuite/23_containers/span/last_assert_neg.cc: Likewise. * testsuite/23_containers/span/last_neg.cc: Likewise. * testsuite/23_containers/span/subspan_2_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_3_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_4_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_5_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_6_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_neg.cc: Likewise. * testsuite/23_containers/span/nodiscard.cc: New test. --- libstdc++-v3/include/std/span | 26 - .../23_containers/span/back_assert_neg.cc | 2 +- .../testsuite/23_containers/span/back_neg.cc | 2 +- .../23_containers/span/first_2_assert_neg.cc | 2 +- .../23_containers/span/first_assert_neg.cc| 2 +- .../testsuite/23_containers/span/first_neg.cc | 2 +- .../23_containers/span/front_assert_neg.cc| 2 +- .../testsuite/23_containers/span/front_neg.cc | 2 +- .../23_containers/span/index_op_assert_neg.cc | 2 +- .../23_containers/span/index_op_neg.cc| 2 +- .../23_containers/span/last_2_assert_neg.cc | 2 +- .../23_containers/span/last_assert_neg.cc | 2 +- .../testsuite/23_containers/span/last_neg.cc | 2 +- .../testsuite/23_containers/span/nodiscard.cc | 58 +++ .../span/subspan_2_assert_neg.cc | 2 +- .../span/subspan_3_assert_neg.cc | 2 +- .../span/subspan_4_assert_neg.cc | 2 +- .../span/subspan_5_assert_neg.cc | 2 +- .../span/subspan_6_assert_neg.cc | 2 +- .../23_containers/span/subspan_assert_neg.cc | 2 +- .../23_containers/span/subspan_neg.cc | 6 +- 21 files changed, 103 insertions(+), 23 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/span/nodiscard.cc diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index d5644a196a2..90d08f18d2c 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -246,20 +246,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // observers + [[nodiscard]] constexpr size_type size() const noexcept { return this->_M_extent._M_extent(); } + [[nodiscard]] constexpr size_type size_bytes() const noexcept { return this->_M_extent._M_extent() * sizeof(element_type); } - [[nodiscard]] constexpr bool + [[nodiscard]] + constexpr bool empty() const noexcept { return size() == 0; } // element access + [[nodiscard]] constexpr reference front() const noexcept { @@ -267,6 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this->_M_ptr; } + [[nodiscard]] constexpr reference back() const noexcept { @@ -274,6 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *(this->_M_ptr + (size() - 1)); } + [[nodiscard]] constexpr reference operator[](size_type __idx) const noexcept { @@ -281,41 +287,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *(this->_M_ptr + __idx); } + [[nodiscard]] constexpr pointer data() const noexcept { return this->_M_ptr; } // iterator support + [[nodiscard]] constexpr iterator begin() const noexcept { return iterator(this->_M_ptr); } + [[nodiscard]] constexpr iterator end() const noexcept { return iterator(this->_M_ptr + this->size()); } + [[nodiscard]] constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(this->end()); } + [[nodiscard]]
[committed] libstdc++: Add [[nodiscard]] to lock types
Tested x86_64-linux. Pushed to trunk. -- >8 -- Adding this attribute means users get a warning when they accidentally create a temporary lock instead of creating an automatic variable with block scope. For std::lock_guard both constructors have side effects (they both take a mutex and so both cause it to be unlocked at the end of the full expression when a temporary is constructed). Ideally we would just put the attribute on the class instead of the constructors, but that doesn't work with GCC (PR c++/85973). For std::unique_lock the default constructor and std::defer_lock_t constructor do not cause any locking or unlocking, so do not need to give a warning. It might still be a mistake to create a temporary using those constructors, but it's harmless and seems unlikely anyway. For a lock object created with one of those constructors you would expect the lock object to be referred to later in the function, and that would not even compile if it was constructed as an unnamed temporary. std::scoped_lock gets the same treatment as std::lock_guard, except that the explicit specialization for zero lockables has no side effects so doesn't need to warn. libstdc++-v3/ChangeLog: * include/bits/std_mutex.h (lock_guard): Add [[nodiscard]] attribute to constructors. * include/bits/unique_lock.h (unique_lock): Likewise. * include/std/mutex (scoped_lock, scoped_lock): Likewise. * testsuite/30_threads/lock_guard/cons/nodiscard.cc: New test. * testsuite/30_threads/scoped_lock/cons/nodiscard.cc: New test. * testsuite/30_threads/unique_lock/cons/nodiscard.cc: New test. --- libstdc++-v3/include/bits/std_mutex.h | 2 + libstdc++-v3/include/bits/unique_lock.h | 5 +++ libstdc++-v3/include/std/mutex| 5 +++ .../30_threads/lock_guard/cons/nodiscard.cc | 20 ++ .../30_threads/scoped_lock/cons/nodiscard.cc | 29 ++ .../30_threads/unique_lock/cons/nodiscard.cc | 40 +++ 6 files changed, 101 insertions(+) create mode 100644 libstdc++-v3/testsuite/30_threads/lock_guard/cons/nodiscard.cc create mode 100644 libstdc++-v3/testsuite/30_threads/scoped_lock/cons/nodiscard.cc create mode 100644 libstdc++-v3/testsuite/30_threads/unique_lock/cons/nodiscard.cc diff --git a/libstdc++-v3/include/bits/std_mutex.h b/libstdc++-v3/include/bits/std_mutex.h index 4693055269d..9ac8c76c9fb 100644 --- a/libstdc++-v3/include/bits/std_mutex.h +++ b/libstdc++-v3/include/bits/std_mutex.h @@ -245,9 +245,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: typedef _Mutex mutex_type; + [[__nodiscard__]] explicit lock_guard(mutex_type& __m) : _M_device(__m) { _M_device.lock(); } + [[__nodiscard__]] lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m) { } // calling thread owns mutex diff --git a/libstdc++-v3/include/bits/unique_lock.h b/libstdc++-v3/include/bits/unique_lock.h index c28e6456ad5..07474d26db5 100644 --- a/libstdc++-v3/include/bits/unique_lock.h +++ b/libstdc++-v3/include/bits/unique_lock.h @@ -66,6 +66,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_device(0), _M_owns(false) { } + [[__nodiscard__]] explicit unique_lock(mutex_type& __m) : _M_device(std::__addressof(__m)), _M_owns(false) { @@ -77,10 +78,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_device(std::__addressof(__m)), _M_owns(false) { } + [[__nodiscard__]] unique_lock(mutex_type& __m, try_to_lock_t) : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock()) { } + [[__nodiscard__]] unique_lock(mutex_type& __m, adopt_lock_t) noexcept : _M_device(std::__addressof(__m)), _M_owns(true) { @@ -88,6 +91,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[__nodiscard__]] unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __atime) : _M_device(std::__addressof(__m)), @@ -95,6 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } template + [[__nodiscard__]] unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rtime) : _M_device(std::__addressof(__m)), diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index bd3a1cbd94d..9d22ce80045 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -744,9 +744,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class scoped_lock { public: + + [[nodiscard]] explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...)) { std::lock(__m...); } + [[nodiscard]] explicit scoped_lock(adopt_lock_t, _MutexTypes&... __m) noexcept : _M_devices(std::tie(__m...)) { } // calling thread owns mutex @@ -779,9 +782,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: using mutex_type = _Mutex; +
[committed] libstdc++: Add [[nodiscard]] in
Tested x86_64-linux. Pushed to trunk. -- >8 -- libstdc++-v3/ChangeLog: * include/std/chrono: Use nodiscard attribute. --- libstdc++-v3/include/std/chrono | 46 + 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 4c5fbfaeb83..33653f8efb1 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -128,11 +128,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using time_point= chrono::time_point; static constexpr bool is_steady = false; + [[nodiscard]] static time_point now() { return from_sys(system_clock::now()); } template + [[nodiscard]] static sys_time> to_sys(const utc_time<_Duration>& __t) { @@ -145,6 +147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] static utc_time> from_sys(const sys_time<_Duration>& __t) { @@ -171,11 +174,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr bool is_steady = false; // XXX true for CLOCK_TAI? // TODO move into lib, use CLOCK_TAI on linux, add extension point. + [[nodiscard]] static time_point now() { return from_utc(utc_clock::now()); } template + [[nodiscard]] static utc_time> to_utc(const tai_time<_Duration>& __t) { @@ -184,6 +189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] static tai_time> from_utc(const utc_time<_Duration>& __t) { @@ -208,11 +214,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr bool is_steady = false; // XXX // TODO move into lib, add extension point. + [[nodiscard]] static time_point now() { return from_utc(utc_clock::now()); } template + [[nodiscard]] static utc_time> to_utc(const gps_time<_Duration>& __t) { @@ -221,6 +229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] static gps_time> from_utc(const utc_time<_Duration>& __t) { @@ -394,6 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Convert a time point to a different clock. template + [[nodiscard]] inline auto clock_cast(const time_point<_SourceClock, _Duration>& __t) requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration> @@ -2620,6 +2630,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION leap_second(const leap_second&) = default; leap_second& operator=(const leap_second&) = default; + [[nodiscard]] constexpr sys_seconds date() const noexcept { @@ -2628,6 +2639,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return sys_seconds(-_M_s); } + [[nodiscard]] constexpr seconds value() const noexcept { @@ -2638,71 +2650,71 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // This can be defaulted because the database will never contain two // leap_second objects with the same date but different signs. - friend constexpr bool + [[nodiscard]] friend constexpr bool operator==(const leap_second&, const leap_second&) noexcept = default; - friend constexpr strong_ordering + [[nodiscard]] friend constexpr strong_ordering operator<=>(const leap_second& __x, const leap_second& __y) noexcept { return __x.date() <=> __y.date(); } template - friend constexpr bool + [[nodiscard]] friend constexpr bool operator==(const leap_second& __x, const sys_time<_Duration>& __y) noexcept { return __x.date() == __y; } template - friend constexpr bool + [[nodiscard]] friend constexpr bool operator<(const leap_second& __x, const sys_time<_Duration>& __y) noexcept { return __x.date() < __y; } template - friend constexpr bool + [[nodiscard]] friend constexpr bool operator<(const sys_time<_Duration>& __x, const leap_second& __y) noexcept { return __x < __y.date(); } template - friend constexpr bool + [[nodiscard]] friend constexpr bool operator>(const leap_second& __x, const sys_time<_Duration>& __y) noexcept { return __y < __x.date(); } template - friend constexpr bool + [[nodiscard]] friend constexpr bool operator>(const sys_time<_Duration>& __x, const leap_second& __y) noexcept { return __y.date() < __x; } template - friend constexpr bool + [[nodiscard]] friend constexpr bool operator<=(const leap_second& __x, - const sys_time<_Duration>& __y) noexcept + const sys_time<_Duration>& __y) noexcept { return !(__y < __x.date()); }
[committed] libstdc++: Add [[nodiscard]] to chrono conversion functions
Tested x86_64-linux. Pushed to trunk. -- >8 -- Also add doxygen comments. libstdc++-v3/ChangeLog: * include/bits/chrono.h (duration_cast, floor, round, abs, ceil) (time_point_cast): Add [[nodiscard]] attribute and doxygen comments. (treat_as_floating_point): Add doxygen commen. --- libstdc++-v3/include/bits/chrono.h | 139 + 1 file changed, 123 insertions(+), 16 deletions(-) diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h index 496e9485a73..22c0be3fbe6 100644 --- a/libstdc++-v3/include/bits/chrono.h +++ b/libstdc++-v3/include/bits/chrono.h @@ -246,8 +246,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @endcond -/// duration_cast +/** Convert a `duration` to type `ToDur`. + * + * If the duration cannot be represented accurately in the result type, + * returns the result of integer truncation (i.e., rounded towards zero). + * + * @tparam _ToDur The result type must be a `duration`. + * @param __d A duration. + * @return The value of `__d` converted to type `_ToDur`. + * @since C++11 + */ template + _GLIBCXX_NODISCARD constexpr __enable_if_is_duration<_ToDur> duration_cast(const duration<_Rep, _Period>& __d) { @@ -260,7 +270,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __dc::__cast(__d); } -/// treat_as_floating_point +/** Trait indicating whether to treat a type as a floating-point type. + * + * The chrono library uses this trait to tell whether a `duration` can + * represent fractional values of the given precision, or only integral + * values. + * + * You should specialize this trait for your own numeric types that are + * used with `duration` and can represent non-integral values. + * + * @since C++11 + */ template struct treat_as_floating_point : is_floating_point<_Rep> @@ -320,8 +340,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201703L # define __cpp_lib_chrono 201611L +/** Convert a `duration` to type `ToDur` and round down. + * + * If the duration cannot be represented exactly in the result type, + * returns the closest value that is less than the argument. + * + * @tparam _ToDur The result type must be a `duration`. + * @param __d A duration. + * @return The value of `__d` converted to type `_ToDur`. + * @since C++17 + */ template - constexpr __enable_if_is_duration<_ToDur> + [[nodiscard]] constexpr __enable_if_is_duration<_ToDur> floor(const duration<_Rep, _Period>& __d) { auto __to = chrono::duration_cast<_ToDur>(__d); @@ -330,8 +360,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __to; } +/** Convert a `duration` to type `ToDur` and round up. + * + * If the duration cannot be represented exactly in the result type, + * returns the closest value that is greater than the argument. + * + * @tparam _ToDur The result type must be a `duration`. + * @param __d A duration. + * @return The value of `__d` converted to type `_ToDur`. + * @since C++17 + */ template - constexpr __enable_if_is_duration<_ToDur> + [[nodiscard]] constexpr __enable_if_is_duration<_ToDur> ceil(const duration<_Rep, _Period>& __d) { auto __to = chrono::duration_cast<_ToDur>(__d); @@ -340,8 +380,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __to; } +/** Convert a `duration` to type `ToDur` and round to the closest value. + * + * If the duration cannot be represented exactly in the result type, + * returns the closest value, rounding ties to even. + * + * @tparam _ToDur The result type must be a `duration` with a + *non-floating-point `rep` type. + * @param __d A duration. + * @return The value of `__d` converted to type `_ToDur`. + * @since C++17 + */ template - constexpr enable_if_t< + [[nodiscard]] constexpr + enable_if_t< __and_<__is_duration<_ToDur>, __not_>>::value, _ToDur> @@ -352,18 +404,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __diff0 = __d - __t0; auto __diff1 = __t1 - __d; if (__diff0 == __diff1) - { + { if (__t0.count() & 1) - return __t1; + return __t1; return __t0; - } + } else if (__diff0 < __diff1) - return __t0; + return __t0; return __t1; } +/** The absolute (non-negative) value of a duration. + * + * @param __d A duration with a signed `rep` type. + * @return A duration of the same type as the argument, with value |d|. + * @since C++17 + */ template - constexpr + [[nodiscard]] constexpr enable_if_t::is_signed, duration<_Rep, _Period>>
[committed] libstdc++: Add nodiscard attribute to mutex try_lock functions
Tested x86_64-linux. Pushed to trunk. -- >8 -- libstdc++-v3/ChangeLog: * include/bits/std_mutex.h (mutex): Add nodiscard attribute to try_lock member function. * include/bits/unique_lock.h (unique_lock): Likewise for try_lock, try_lock_until, try_lock_for member functions, and owns_lock and mutex member functions. * include/std/mutex (recursive_mutex): Likewise for try_lock member function. (timed_mutex, recursive_timed_mutex, try_lock): Likewise for try_lock, try_lock_until, try_lock_for member functions. (try_lock): Likewise for non-member function. * include/std/shared_mutex (shared_mutex): Likewise for try_lock and try_lock_shared member functions. (shared_timed_mutex): Likewise for try_lock, try_lock_for, try_lock_shared, try_lock_shared_for, try_lock_until, and try_lock_shared_until member functions. (shared_lock): Likewise for try_lock, try_lock, try_lock_for, try_lock_until, owns_lock, and mutex member functions. * testsuite/30_threads/recursive_timed_mutex/try_lock_until/clock_neg.cc: Cast discarded value expression to void. * testsuite/30_threads/shared_lock/locking/3.cc: Likewise. * testsuite/30_threads/shared_lock/locking/4.cc: Likewise. * testsuite/30_threads/shared_lock/locking/clock_neg.cc: Likewise. * testsuite/30_threads/shared_timed_mutex/try_lock_until/clock_neg.cc: Likewise. * testsuite/30_threads/timed_mutex/try_lock_until/clock_neg.cc: Likewise. * testsuite/30_threads/try_lock/4.cc: Likewise. * testsuite/30_threads/unique_lock/cons/60497.cc: Likewise. * testsuite/30_threads/unique_lock/locking/3.cc: Likewise. * testsuite/30_threads/unique_lock/locking/clock_neg.cc: Likewise. --- libstdc++-v3/include/bits/std_mutex.h | 1 + libstdc++-v3/include/bits/unique_lock.h | 5 + libstdc++-v3/include/std/mutex| 14 libstdc++-v3/include/std/shared_mutex | 22 --- .../try_lock_until/clock_neg.cc | 4 ++-- .../30_threads/shared_lock/locking/3.cc | 2 +- .../30_threads/shared_lock/locking/4.cc | 2 +- .../shared_lock/locking/clock_neg.cc | 4 ++-- .../try_lock_until/clock_neg.cc | 4 ++-- .../timed_mutex/try_lock_until/clock_neg.cc | 4 ++-- .../testsuite/30_threads/try_lock/4.cc| 2 +- .../30_threads/unique_lock/cons/60497.cc | 2 +- .../30_threads/unique_lock/locking/3.cc | 2 +- .../unique_lock/locking/clock_neg.cc | 4 ++-- 14 files changed, 54 insertions(+), 18 deletions(-) diff --git a/libstdc++-v3/include/bits/std_mutex.h b/libstdc++-v3/include/bits/std_mutex.h index b22e0e12793..68f5fb9ed65 100644 --- a/libstdc++-v3/include/bits/std_mutex.h +++ b/libstdc++-v3/include/bits/std_mutex.h @@ -117,6 +117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_system_error(__e); } +_GLIBCXX_NODISCARD bool try_lock() noexcept { diff --git a/libstdc++-v3/include/bits/unique_lock.h b/libstdc++-v3/include/bits/unique_lock.h index 9ed7ba25766..c6402d94e85 100644 --- a/libstdc++-v3/include/bits/unique_lock.h +++ b/libstdc++-v3/include/bits/unique_lock.h @@ -143,6 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + _GLIBCXX_NODISCARD bool try_lock() { @@ -158,6 +159,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + _GLIBCXX_NODISCARD bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { @@ -173,6 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + _GLIBCXX_NODISCARD bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { @@ -215,6 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret; } + _GLIBCXX_NODISCARD bool owns_lock() const noexcept { return _M_owns; } @@ -222,6 +226,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION explicit operator bool() const noexcept { return owns_lock(); } + _GLIBCXX_NODISCARD mutex_type* mutex() const noexcept { return _M_device; } diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index b310c15687d..aca5f91e03c 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -124,6 +124,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_system_error(__e); } +_GLIBCXX_NODISCARD bool try_lock() noexcept { @@ -253,6 +254,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_system_error(__e); } +_GLIBCXX_NODISCARD bool try_lock() noexcept { @@ -261,11 +263,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + _GLIBCXX_NODISCARD bool try_lock_for(const
[committed] libstdc++: Add nodiscard attribute to filesystem operations
Tested x86_64-linux, pushed to trunk. -- >8 -- Some of these are not truly "pure" because they access the file system, e.g. exists and file_size, but they do not modify anything and are only useful for the return value. If you really want to use one of those functions just to check whether an error is reported (either via an exception or an error_code& argument) you can still do so, but you need to cast the discarded result to void. Several tests need such a change, because they were indeed only calling the functions to check for expected errors. libstdc++-v3/ChangeLog: * include/bits/fs_ops.h: Add nodiscard to all pure functions. * include/experimental/bits/fs_ops.h: Likewise. * testsuite/27_io/filesystem/operations/all.cc: Do not discard results of absolute and canonical. * testsuite/27_io/filesystem/operations/absolute.cc: Cast discarded result to void. * testsuite/27_io/filesystem/operations/canonical.cc: Likewise. * testsuite/27_io/filesystem/operations/exists.cc: Likewise. * testsuite/27_io/filesystem/operations/is_empty.cc: Likewise. * testsuite/27_io/filesystem/operations/read_symlink.cc: Likewise. * testsuite/27_io/filesystem/operations/status.cc: Likewise. * testsuite/27_io/filesystem/operations/symlink_status.cc: Likewise. * testsuite/27_io/filesystem/operations/temp_directory_path.cc: Likewise. * testsuite/experimental/filesystem/operations/canonical.cc: Likewise. * testsuite/experimental/filesystem/operations/exists.cc: Likewise. * testsuite/experimental/filesystem/operations/is_empty.cc: Likewise. * testsuite/experimental/filesystem/operations/read_symlink.cc: Likewise. * testsuite/experimental/filesystem/operations/temp_directory_path.cc: Likewise. --- libstdc++-v3/include/bits/fs_ops.h| 79 +++ .../include/experimental/bits/fs_ops.h| 71 + .../27_io/filesystem/operations/absolute.cc | 2 +- .../27_io/filesystem/operations/all.cc| 8 +- .../27_io/filesystem/operations/canonical.cc | 4 +- .../27_io/filesystem/operations/exists.cc | 2 +- .../27_io/filesystem/operations/is_empty.cc | 4 +- .../filesystem/operations/read_symlink.cc | 2 +- .../27_io/filesystem/operations/status.cc | 2 +- .../filesystem/operations/symlink_status.cc | 2 +- .../operations/temp_directory_path.cc | 4 +- .../filesystem/operations/canonical.cc| 6 +- .../filesystem/operations/exists.cc | 2 +- .../filesystem/operations/is_empty.cc | 4 +- .../filesystem/operations/read_symlink.cc | 2 +- .../operations/temp_directory_path.cc | 4 +- 16 files changed, 174 insertions(+), 24 deletions(-) diff --git a/libstdc++-v3/include/bits/fs_ops.h b/libstdc++-v3/include/bits/fs_ops.h index 0281c6540d0..1ae8fe12374 100644 --- a/libstdc++-v3/include/bits/fs_ops.h +++ b/libstdc++-v3/include/bits/fs_ops.h @@ -44,10 +44,16 @@ namespace filesystem * @{ */ + [[nodiscard]] path absolute(const path& __p); + + [[nodiscard]] path absolute(const path& __p, error_code& __ec); + [[nodiscard]] path canonical(const path& __p); + + [[nodiscard]] path canonical(const path& __p, error_code& __ec); inline void @@ -100,25 +106,34 @@ namespace filesystem void create_symlink(const path& __to, const path& __new_symlink, error_code& __ec) noexcept; + [[nodiscard]] path current_path(); + + [[nodiscard]] path current_path(error_code& __ec); + void current_path(const path& __p); void current_path(const path& __p, error_code& __ec) noexcept; + [[nodiscard]] bool equivalent(const path& __p1, const path& __p2); + [[nodiscard]] bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept; + [[nodiscard]] inline bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } + [[nodiscard]] inline bool exists(const path& __p) { return exists(status(__p)); } + [[nodiscard]] inline bool exists(const path& __p, error_code& __ec) noexcept { @@ -131,63 +146,85 @@ namespace filesystem return false; } + [[nodiscard]] uintmax_t file_size(const path& __p); + + [[nodiscard]] uintmax_t file_size(const path& __p, error_code& __ec) noexcept; + [[nodiscard]] uintmax_t hard_link_count(const path& __p); + + [[nodiscard]] uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept; + [[nodiscard]] inline bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } + [[nodiscard]] inline bool is_block_file(const path& __p) { return is_block_file(status(__p)); } + [[nodiscard]] inline bool is_block_file(const path& __p, error_code& __ec) noexcept
[committed] libstdc++: Add [[nodiscard]] to experimental::randint
Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/experimental/random (experimental::randint): Add nodiscard attribute. Tested powerpc64le-linux. Committed to trunk. commit 20ce14c7991fbb498e32a0f5e3b01ae88c9f5e9a Author: Jonathan Wakely Date: Thu Aug 12 18:05:24 2021 libstdc++: Add [[nodiscard]] to experimental::randint Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: * include/experimental/random (experimental::randint): Add nodiscard attribute. diff --git a/libstdc++-v3/include/experimental/random b/libstdc++-v3/include/experimental/random index 2c2b359ff41..d7431e33e98 100644 --- a/libstdc++-v3/include/experimental/random +++ b/libstdc++-v3/include/experimental/random @@ -50,6 +50,7 @@ inline namespace fundamentals_v2 { // 13.2.2.1, Function template randint template +[[__nodiscard__]] inline _IntType randint(_IntType __a, _IntType __b) {
[committed] libstdc++: Add nodiscard attribute to cast-like functions
Add [[nodiscard]] to functions that are effectively just a static_cast, as per P2351. Also add it to std::addressof. libstdc++-v3/ChangeLog: * include/bits/move.h (forward, move, move_if_noexcept) (addressof): Add _GLIBCXX_NODISCARD. * include/bits/ranges_cmp.h (identity::operator()): Add nodiscard attribute. * include/c_global/cstddef (to_integer): Likewise. * include/std/bit (bit_cast): Likewise. * include/std/utility (as_const, to_underlying): Likewise. Tested powerpc64le-linux. Committed to trunk. commit 406f58e1e38e92e4b881f3666b596843da308783 Author: Jonathan Wakely Date: Tue Apr 6 14:41:29 2021 libstdc++: Add nodiscard attribute to cast-like functions Add [[nodiscard]] to functions that are effectively just a static_cast, as per P2351. Also add it to std::addressof. libstdc++-v3/ChangeLog: * include/bits/move.h (forward, move, move_if_noexcept) (addressof): Add _GLIBCXX_NODISCARD. * include/bits/ranges_cmp.h (identity::operator()): Add nodiscard attribute. * include/c_global/cstddef (to_integer): Likewise. * include/std/bit (bit_cast): Likewise. * include/std/utility (as_const, to_underlying): Likewise. diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index feacae084c9..3abbb37ceeb 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -72,6 +72,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * This function is used to implement "perfect forwarding". */ template +_GLIBCXX_NODISCARD constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) noexcept { return static_cast<_Tp&&>(__t); } @@ -83,6 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * This function is used to implement "perfect forwarding". */ template +_GLIBCXX_NODISCARD constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type&& __t) noexcept { @@ -97,6 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @return The parameter cast to an rvalue-reference to allow moving it. */ template +_GLIBCXX_NODISCARD constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { return static_cast::type&&>(__t); } @@ -116,6 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * type is copyable, in which case an lvalue-reference is returned instead. */ template +_GLIBCXX_NODISCARD constexpr typename conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type move_if_noexcept(_Tp& __x) noexcept @@ -136,6 +140,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @return The actual address. */ template +_GLIBCXX_NODISCARD inline _GLIBCXX17_CONSTEXPR _Tp* addressof(_Tp& __r) noexcept { return std::__addressof(__r); } diff --git a/libstdc++-v3/include/bits/ranges_cmp.h b/libstdc++-v3/include/bits/ranges_cmp.h index 3f71d31e5a6..f859a33b2c1 100644 --- a/libstdc++-v3/include/bits/ranges_cmp.h +++ b/libstdc++-v3/include/bits/ranges_cmp.h @@ -47,6 +47,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct identity { template + [[nodiscard]] constexpr _Tp&& operator()(_Tp&& __t) const noexcept { return std::forward<_Tp>(__t); } diff --git a/libstdc++-v3/include/c_global/cstddef b/libstdc++-v3/include/c_global/cstddef index 11c808cab28..13ef7f03c12 100644 --- a/libstdc++-v3/include/c_global/cstddef +++ b/libstdc++-v3/include/c_global/cstddef @@ -169,6 +169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __l = __l ^ __r; } template +[[nodiscard]] constexpr _IntegerType to_integer(__byte_op_t<_IntegerType> __b) noexcept { return _IntegerType(__b); } diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index 8638a02c8a6..fb78578448c 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Create a value of type `To` from the bits of `from`. template +[[nodiscard]] constexpr _To bit_cast(const _From& __from) noexcept { diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index fb19d62968f..3e68f682e00 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -386,7 +386,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_as_const 201510 template -constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; } +[[nodiscard]] +constexpr add_const_t<_Tp>& +as_const(_Tp& __t) noexcept +{ return __t; } template void as_const(const _Tp&&) = delete; @@ -466,6 +469,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_to_underlying 202102L /// Convert an object of enumeration type to its underlying type. template +[[nodiscard]] constexpr underlying_type_t<_Tp>