[libc++] Add [[nodiscard]] extensions to the functions in <bit>

Reviewed By: #libc, ldionne, Mordante

Spies: Mordante, ldionne, libcxx-commits

Differential Revision: https://reviews.llvm.org/D152653
This commit is contained in:
Nikolas Klauser 2023-06-13 07:57:26 -07:00
parent 79e53ee040
commit 7d3bba5e2f
15 changed files with 111 additions and 27 deletions

View File

@ -383,12 +383,20 @@ which no dialect declares as such (See the second form described above).
* ``as_const``
* ``binary_search``
* ``bit_cast``
* ``bit_ceil``
* ``bit_floor``
* ``bit_width``
* ``byteswap``
* ``cbrt``
* ``ceil``
* ``clamp``
* ``copysign``
* ``count_if``
* ``count``
* ``countl_zero``
* ``countl_one``
* ``countr_zero``
* ``countr_one``
* ``equal_range``
* ``equal``
* ``fabs``
@ -403,6 +411,7 @@ which no dialect declares as such (See the second form described above).
* ``forward``
* ``fpclassify``
* ``get_temporary_buffer``
* ``has_single_bit``
* ``identity::operator()``
* ``includes``
* ``is_heap_until``
@ -437,6 +446,7 @@ which no dialect declares as such (See the second form described above).
* ``move``
* ``nearbyint``
* ``none_of``
* ``popcount``
* ``ranges::adjacent_find``
* ``ranges::all_of``
* ``ranges::any_of``

View File

@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept {
if (__t < 2)
return 1;
const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u));

View File

@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept {
return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t);
}

View File

@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept {
return __t == 0 ? 0 : std::__bit_log2(__t) + 1;
}

View File

@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
template <integral _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
if constexpr (sizeof(_Tp) == 1) {
return __val;

View File

@ -24,13 +24,13 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); }
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); }
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
# ifndef _LIBCPP_HAS_NO_INT128
@ -86,12 +86,12 @@ int __countl_zero(_Tp __t) _NOEXCEPT
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept {
return std::__countl_zero(__t);
}
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept {
return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
}

View File

@ -23,19 +23,19 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); }
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); }
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
if (__t == 0)
return numeric_limits<_Tp>::digits;
@ -57,7 +57,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {
}
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {
return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;
}

View File

@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept {
return __t != 0 && (((__t & (__t - 1)) == 0));
}

View File

@ -35,7 +35,7 @@ int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popco
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept {
if (sizeof(_Tp) <= sizeof(unsigned int))
return std::__libcpp_popcount(static_cast<unsigned int>(__t));
else if (sizeof(_Tp) <= sizeof(unsigned long))

View File

@ -34,7 +34,7 @@ _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
const unsigned int __dig = numeric_limits<_Tp>::digits;
if ((__cnt % __dig) == 0)
return __t;
@ -42,7 +42,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
}
template <__libcpp_unsigned_integer _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
return std::__rotr(__t, __cnt);
}

View File

@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// 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, c++11, c++14, c++17
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_NODISCARD_EXT
// Check that <bit> functions aren't marked [[nodiscard]] when
// _LIBCPP_DISBALE_NODISCARD_EXT is defined
#include <bit>
#include "test_macros.h"
void func() {
std::bit_cast<unsigned int>(42);
std::bit_ceil(0u);
std::bit_floor(0u);
std::bit_width(0u);
#if TEST_STD_VER >= 23
std::byteswap(0u);
#endif
std::countl_zero(0u);
std::countl_one(0u);
std::countr_zero(0u);
std::countr_one(0u);
std::has_single_bit(0u);
std::popcount(0u);
}

View File

@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// 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, c++11, c++14, c++17
// check that <bit> functions are marked [[nodiscard]]
#include <bit>
#include "test_macros.h"
void func() {
std::bit_cast<unsigned int>(42); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::bit_ceil(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::bit_floor(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::bit_width(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#if TEST_STD_VER >= 23
std::byteswap(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#endif
std::countl_zero(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::countl_one(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::countr_zero(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::countr_one(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::has_single_bit(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::popcount(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}

View File

@ -173,10 +173,6 @@ void test_nontemplate_cast_wrappers()
std::to_integer<int>(b);
#endif
#if TEST_STD_VER > 17
std::bit_cast<unsigned int>(42);
#endif
#if TEST_STD_VER > 20
enum E { Apple, Orange } e = Apple;
std::to_underlying(e);

View File

@ -337,11 +337,6 @@ void test_nontemplate_cast_wrappers()
std::to_integer<int>(b);
#endif
#if TEST_STD_VER > 17
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::bit_cast<unsigned int>(42);
#endif
#if TEST_STD_VER > 20
enum E { Apple, Orange } e = Apple;
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}

View File

@ -0,0 +1,18 @@
//===----------------------------------------------------------------------===//
//
// 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, c++11, c++14, c++17
// Check that std::rotl and std::rotr are marked [[nodiscard]]
#include <bit>
void func() {
std::rotl(0u, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
std::rotr(0u, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}