[libcxx-commits] [libcxx] 7d3bba5 - [libc++] Add [[nodiscard]] extensions to the functions in <bit>
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 13 08:01:41 PDT 2023
Author: Nikolas Klauser
Date: 2023-06-13T08:01:34-07:00
New Revision: 7d3bba5e2fe677d04614bf4ba02a55ee3da4ec02
URL: https://github.com/llvm/llvm-project/commit/7d3bba5e2fe677d04614bf4ba02a55ee3da4ec02
DIFF: https://github.com/llvm/llvm-project/commit/7d3bba5e2fe677d04614bf4ba02a55ee3da4ec02.diff
LOG: [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
Added:
libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.compile.pass.cpp
libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.verify.cpp
libcxx/test/std/numerics/bit/bitops.rot/nodiscard.verify.cpp
Modified:
libcxx/docs/UsingLibcxx.rst
libcxx/include/__bit/bit_ceil.h
libcxx/include/__bit/bit_floor.h
libcxx/include/__bit/bit_width.h
libcxx/include/__bit/byteswap.h
libcxx/include/__bit/countl.h
libcxx/include/__bit/countr.h
libcxx/include/__bit/has_single_bit.h
libcxx/include/__bit/popcount.h
libcxx/include/__bit/rotate.h
libcxx/test/libcxx/diagnostics/nodiscard_extensions.compile.pass.cpp
libcxx/test/libcxx/diagnostics/nodiscard_extensions.verify.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 3b22ac8274281..27a836122976e 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -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``
diff --git a/libcxx/include/__bit/bit_ceil.h b/libcxx/include/__bit/bit_ceil.h
index 1332900ae799e..f6bcb3511026c 100644
--- a/libcxx/include/__bit/bit_ceil.h
+++ b/libcxx/include/__bit/bit_ceil.h
@@ -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));
diff --git a/libcxx/include/__bit/bit_floor.h b/libcxx/include/__bit/bit_floor.h
index b2e38092f2d7f..cf5cf5803ad64 100644
--- a/libcxx/include/__bit/bit_floor.h
+++ b/libcxx/include/__bit/bit_floor.h
@@ -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);
}
diff --git a/libcxx/include/__bit/bit_width.h b/libcxx/include/__bit/bit_width.h
index 4381f227f5e56..a2020a01421e3 100644
--- a/libcxx/include/__bit/bit_width.h
+++ b/libcxx/include/__bit/bit_width.h
@@ -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;
}
diff --git a/libcxx/include/__bit/byteswap.h b/libcxx/include/__bit/byteswap.h
index b290e80a5c681..a1e1b530975e3 100644
--- a/libcxx/include/__bit/byteswap.h
+++ b/libcxx/include/__bit/byteswap.h
@@ -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;
diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h
index 86eaee0c1b3b5..5d5744ac9a652 100644
--- a/libcxx/include/__bit/countl.h
+++ b/libcxx/include/__bit/countl.h
@@ -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;
}
diff --git a/libcxx/include/__bit/countr.h b/libcxx/include/__bit/countr.h
index d3ca5b6c94f1e..66ca5e7e66f2b 100644
--- a/libcxx/include/__bit/countr.h
+++ b/libcxx/include/__bit/countr.h
@@ -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;
}
diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h
index b89f5995b32db..a4e178060a73a 100644
--- a/libcxx/include/__bit/has_single_bit.h
+++ b/libcxx/include/__bit/has_single_bit.h
@@ -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));
}
diff --git a/libcxx/include/__bit/popcount.h b/libcxx/include/__bit/popcount.h
index 33b94cff71223..62f4786bceaf5 100644
--- a/libcxx/include/__bit/popcount.h
+++ b/libcxx/include/__bit/popcount.h
@@ -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))
diff --git a/libcxx/include/__bit/rotate.h b/libcxx/include/__bit/rotate.h
index 5aa7518b3c57b..e9f4c8d474b0a 100644
--- a/libcxx/include/__bit/rotate.h
+++ b/libcxx/include/__bit/rotate.h
@@ -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);
}
diff --git a/libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.compile.pass.cpp b/libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.compile.pass.cpp
new file mode 100644
index 0000000000000..a1400336cefde
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.compile.pass.cpp
@@ -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);
+}
diff --git a/libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.verify.cpp b/libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.verify.cpp
new file mode 100644
index 0000000000000..79cb56a6f4380
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.verify.cpp
@@ -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}}
+}
diff --git a/libcxx/test/libcxx/diagnostics/nodiscard_extensions.compile.pass.cpp b/libcxx/test/libcxx/diagnostics/nodiscard_extensions.compile.pass.cpp
index 0cc86e2a77cfd..e9fab0c75a98e 100644
--- a/libcxx/test/libcxx/diagnostics/nodiscard_extensions.compile.pass.cpp
+++ b/libcxx/test/libcxx/diagnostics/nodiscard_extensions.compile.pass.cpp
@@ -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);
diff --git a/libcxx/test/libcxx/diagnostics/nodiscard_extensions.verify.cpp b/libcxx/test/libcxx/diagnostics/nodiscard_extensions.verify.cpp
index 3d0dd2ab22ad6..d7a26d99e5223 100644
--- a/libcxx/test/libcxx/diagnostics/nodiscard_extensions.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/nodiscard_extensions.verify.cpp
@@ -337,11 +337,6 @@ void test_nontemplate_cast_wrappers()
std::to_integer<int>(b);
#endif
-#if TEST_STD_VER > 17
- // expected-warning at +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 at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
diff --git a/libcxx/test/std/numerics/bit/bitops.rot/nodiscard.verify.cpp b/libcxx/test/std/numerics/bit/bitops.rot/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..885534a85c3cb
--- /dev/null
+++ b/libcxx/test/std/numerics/bit/bitops.rot/nodiscard.verify.cpp
@@ -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}}
+}
More information about the libcxx-commits
mailing list