Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libcxx/include/__condition_variable/condition_variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);

typedef __libcpp_condvar_t* native_handle_type;
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }

private:
void
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__mutex/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_CAPABILITY("mutex") mutex {
# endif

_LIBCPP_ACQUIRE_CAPABILITY() void lock();
_LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
[[__nodiscard__]] _LIBCPP_TRY_ACQUIRE_CAPABILITY(true) bool try_lock() _NOEXCEPT;
_LIBCPP_RELEASE_CAPABILITY void unlock() _NOEXCEPT;

typedef __libcpp_mutex_t* native_handle_type;
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
};

static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow");
Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/__thread/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,13 @@ class _LIBCPP_EXPORTED_FROM_ABI thread {

_LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); }

_LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
void join();
void detach();
_LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }

static unsigned hardware_concurrency() _NOEXCEPT;
[[__nodiscard__]] static unsigned hardware_concurrency() _NOEXCEPT;
};

inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); }
Expand Down
4 changes: 3 additions & 1 deletion libcxx/include/barrier
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ class barrier {
public:
using arrival_token = typename __barrier_base<_CompletionF>::arrival_token;

static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return __barrier_base<_CompletionF>::max(); }
[[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
return __barrier_base<_CompletionF>::max();
}

_LIBCPP_HIDE_FROM_ABI explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
: __b_(__count, std::move(__completion)) {
Expand Down
6 changes: 4 additions & 2 deletions libcxx/include/latch
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class latch {
atomic<ptrdiff_t> __a_;

public:
static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { return numeric_limits<ptrdiff_t>::max(); }
[[nodiscard]] static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
return numeric_limits<ptrdiff_t>::max();
}

inline _LIBCPP_HIDE_FROM_ABI constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) {
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
Expand All @@ -97,7 +99,7 @@ public:
if (__old == __update)
__a_.notify_all();
}
inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool try_wait() const noexcept {
auto __value = __a_.load(memory_order_acquire);
return try_wait_impl(__value);
}
Expand Down
21 changes: 11 additions & 10 deletions libcxx/include/mutex
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ public:
recursive_mutex& operator=(const recursive_mutex&) = delete;

void lock();
bool try_lock() _NOEXCEPT;
[[__nodiscard__]] bool try_lock() _NOEXCEPT;
void unlock() _NOEXCEPT;

typedef __libcpp_recursive_mutex_t* native_handle_type;

_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; }
};

class _LIBCPP_EXPORTED_FROM_ABI timed_mutex {
Expand All @@ -251,14 +251,14 @@ public:

public:
void lock();
bool try_lock() _NOEXCEPT;
[[__nodiscard__]] bool try_lock() _NOEXCEPT;
template <class _Rep, class _Period>
_LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
return try_lock_until(chrono::steady_clock::now() + __d);
}

template <class _Clock, class _Duration>
_LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
using namespace chrono;
unique_lock<mutex> __lk(__m_);
bool __no_timeout = _Clock::now() < __t;
Expand Down Expand Up @@ -288,14 +288,14 @@ public:
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

void lock();
bool try_lock() _NOEXCEPT;
[[__nodiscard__]] bool try_lock() _NOEXCEPT;
template <class _Rep, class _Period>
_LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
return try_lock_until(chrono::steady_clock::now() + __d);
}

template <class _Clock, class _Duration>
_LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
using namespace chrono;
__thread_id __id = this_thread::get_id();
unique_lock<mutex> __lk(__m_);
Expand All @@ -320,7 +320,7 @@ public:
};

template <class _L0, class _L1>
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
unique_lock<_L0> __u0(__l0, try_to_lock_t());
if (__u0.owns_lock()) {
if (__l1.try_lock()) {
Expand All @@ -335,7 +335,8 @@ _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0,
# ifndef _LIBCPP_CXX03_LANG

template <class _L0, class _L1, class _L2, class... _L3>
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
[[__nodiscard__]] _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
_LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
int __r = 0;
unique_lock<_L0> __u0(__l0, try_to_lock);
if (__u0.owns_lock()) {
Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/semaphore
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class counting_semaphore {
public:
static_assert(__least_max_value >= 0, "The least maximum value must be a positive number");

static constexpr ptrdiff_t max() noexcept { return __least_max_value; }
[[nodiscard]] static constexpr ptrdiff_t max() noexcept { return __least_max_value; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, the try_* functions below.


_LIBCPP_HIDE_FROM_ABI constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) {
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
Expand All @@ -156,12 +156,12 @@ public:
}
_LIBCPP_HIDE_FROM_ABI void acquire() { __semaphore_.acquire(); }
template <class _Rep, class _Period>
_LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) {
return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
}
_LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire() { return __semaphore_.try_acquire(); }
template <class _Clock, class _Duration>
_LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) {
auto const __current = _Clock::now();
if (__current >= __abs_time)
return try_acquire();
Expand Down
144 changes: 144 additions & 0 deletions libcxx/test/libcxx/thread/nodiscard.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03
// UNSUPPORTED: no-threads

// Check that functions are marked [[nodiscard]]

#include <chrono>
#include <barrier>
#include <latch>
#include <mutex>
#include <semaphore>
#include <thread>

#include "test_macros.h"

const auto timePoint = std::chrono::steady_clock::now();

void test() {
// Threads
{
std::thread th;

th.joinable(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
th.get_id(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
th.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
th.hardware_concurrency(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
#if TEST_STD_VER >= 20
{
std::jthread jt;

jt.joinable(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
jt.get_id(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
jt.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
jt.get_stop_source(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
jt.get_stop_token(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
jt.hardware_concurrency(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
#endif

// Mutual exclusion

{ // <mutex>
std::mutex m;

m.try_lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
m.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{
std::recursive_mutex m;

m.try_lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
m.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{
std::timed_mutex m;

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
m.try_lock();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
m.try_lock_for(std::chrono::nanoseconds{82});
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
m.try_lock_until(timePoint);
}
{
std::recursive_timed_mutex m;

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
m.try_lock();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
m.try_lock_for(std::chrono::nanoseconds{82});
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
m.try_lock_until(timePoint);
}
{
std::mutex m1;
std::mutex m2;
std::mutex m3;

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::try_lock(m1, m2);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::try_lock(m1, m2, m3);
}

// Condition variables

{ // <condition_variable>
std::condition_variable cv;

cv.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}

#if TEST_STD_VER >= 20

// Semaphores

{ // <semaphore>
std::counting_semaphore<> cs{0};

cs.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cs.try_acquire_for(std::chrono::nanoseconds{82});
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cs.try_acquire();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cs.try_acquire_until(timePoint);

std::binary_semaphore bs{0};

bs.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
bs.try_acquire_for(std::chrono::nanoseconds{82});
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
bs.try_acquire();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
bs.try_acquire_until(timePoint);
}

// Latches and barriers

{ // <barrier>
std::barrier<> b{94};

b.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{ // <latch>
std::latch l{94};

l.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
l.try_wait(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}

#endif
}
29 changes: 0 additions & 29 deletions libcxx/test/std/thread/thread.jthread/nodiscard.verify.cpp

This file was deleted.

Loading