[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