Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
12 changes: 6 additions & 6 deletions libcxx/include/__compare/is_eq.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER >= 20

_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lt(partial_ordering __c) noexcept { return __c < 0; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexcept { return __c <= 0; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; }

#endif // _LIBCPP_STD_VER >= 20

Expand Down
18 changes: 9 additions & 9 deletions libcxx/include/__coroutine/coroutine_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ struct coroutine_handle<void> {
}

// [coroutine.handle.export.import], export/import
_LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }

_LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
coroutine_handle __tmp;
__tmp.__handle_ = __addr;
return __tmp;
Expand All @@ -55,7 +55,7 @@ struct coroutine_handle<void> {
// [coroutine.handle.observers], observers
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }

_LIBCPP_HIDE_FROM_ABI bool done() const {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
return __builtin_coro_done(__handle_);
}
Expand Down Expand Up @@ -100,7 +100,7 @@ struct coroutine_handle {

_LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}

_LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
using _RawPromise = __remove_cv_t<_Promise>;
coroutine_handle __tmp;
__tmp.__handle_ =
Expand All @@ -114,9 +114,9 @@ struct coroutine_handle {
}

// [coroutine.handle.export.import], export/import
_LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }

_LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
coroutine_handle __tmp;
__tmp.__handle_ = __addr;
return __tmp;
Expand All @@ -130,7 +130,7 @@ struct coroutine_handle {
// [coroutine.handle.observers], observers
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }

_LIBCPP_HIDE_FROM_ABI bool done() const {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool done() const {
_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
return __builtin_coro_done(__handle_);
}
Expand All @@ -150,7 +150,7 @@ struct coroutine_handle {
}

// [coroutine.handle.promise], promise access
_LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
}

Expand All @@ -165,7 +165,7 @@ struct coroutine_handle {
// [coroutine.handle.hash]
template <class _Tp>
struct hash<coroutine_handle<_Tp>> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
return hash<void*>()(__v.address());
}
};
Expand Down
10 changes: 6 additions & 4 deletions libcxx/include/__coroutine/noop_coroutine_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ struct coroutine_handle<noop_coroutine_promise> {

// [coroutine.handle.noop.observers], observers
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; }
_LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; }

// [coroutine.handle.noop.resumption], resumption
_LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {}
_LIBCPP_HIDE_FROM_ABI constexpr void resume() const noexcept {}
_LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {}

// [coroutine.handle.noop.promise], promise access
_LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept {
return *static_cast<noop_coroutine_promise*>(
__builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false));
}

// [coroutine.handle.noop.address], address
_LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }

private:
_LIBCPP_HIDE_FROM_ABI friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
Expand Down Expand Up @@ -86,7 +86,9 @@ inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::
# endif

// [coroutine.noop.coroutine]
inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept {
return noop_coroutine_handle();
}

_LIBCPP_END_NAMESPACE_STD

Expand Down
14 changes: 7 additions & 7 deletions libcxx/include/__utility/cmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ concept __comparison_can_promote_to =
sizeof(_Tp) < sizeof(_Ip) || (sizeof(_Tp) == sizeof(_Ip) && __signed_integer<_Tp>);

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
return __t == __u;
else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
Expand All @@ -45,12 +45,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept {
}

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept {
return !std::cmp_equal(__t, __u);
}

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
return __t < __u;
else if constexpr (__comparison_can_promote_to<_Tp, int> && __comparison_can_promote_to<_Up, int>)
Expand All @@ -64,22 +64,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less(_Tp __t, _Up __u) noexcept {
}

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept {
return std::cmp_less(__u, __t);
}

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept {
return !std::cmp_greater(__t, __u);
}

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept {
return !std::cmp_less(__t, __u);
}

template <__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer _Up>
_LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool in_range(_Up __u) noexcept {
return std::cmp_less_equal(__u, numeric_limits<_Tp>::max()) &&
std::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
}
Expand Down
12 changes: 9 additions & 3 deletions libcxx/include/initializer_list
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,17 @@ public:

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT { return __size_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT {
return __size_;
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT { return __begin_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT {
return __begin_;
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT { return __begin_ + __size_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end() const _NOEXCEPT {
return __begin_ + __size_;
}
};

template <class _Ep>
Expand Down
28 changes: 22 additions & 6 deletions libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,40 @@

// check that <utility> functions are marked [[nodiscard]]

// clang-format off

#include <utility>

#include "test_macros.h"

void test() {
int i = 0;

std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::move_if_noexcept(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::move_if_noexcept(i);

#if TEST_STD_VER >= 17
std::as_const(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#endif

#if TEST_STD_VER >= 20
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cmp_equal(94, 82);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cmp_not_equal(94, 82);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cmp_less(94, 82);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cmp_greater(94, 82);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cmp_less_equal(94, 82);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::cmp_greater_equal(94, 82);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::in_range<long>(49);
#endif

#if TEST_STD_VER >= 23
enum E { Apple, Orange } e = Apple;
std::to_underlying(e); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
Expand Down
91 changes: 91 additions & 0 deletions libcxx/test/libcxx/language.support/nodiscard.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//===----------------------------------------------------------------------===//
//
// 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

// check that <utility> functions are marked [[nodiscard]]

#include <compare>
#include <coroutine>
#include <functional>
#include <initializer_list>

#include "test_macros.h"

void test() {
#if TEST_STD_VER >= 20
{ // <compare>
int x = 94;
int y = 82;
auto oRes = x <=> y;

std::is_eq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_neq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_lt(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_lteq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_gt(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::is_gteq(oRes); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
#endif

#if TEST_STD_VER >= 20
{ // <coroutine>
struct EmptyPromise {
} promise;

{
std::coroutine_handle<void> cr{};

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.address();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::coroutine_handle<void>::from_address(&promise);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.done();

std::hash<std::coroutine_handle<void>> hash;
hash(cr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{
std::coroutine_handle<EmptyPromise> cr;

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::coroutine_handle<EmptyPromise>::from_promise(promise);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.address();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::coroutine_handle<EmptyPromise>::from_address(&promise);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.done();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.promise();
}
{
std::coroutine_handle<std::noop_coroutine_promise> cr = std::noop_coroutine();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.done();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.promise();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
cr.address();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::noop_coroutine();
}
}
#endif

{ // <initializer_list>
std::initializer_list<int> il{94, 82, 49};

il.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
il.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
il.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
}
Loading