-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[libc++][tuple] Applied [[nodiscard]]
#172008
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
6ddf3dd to
aba73cc
Compare
|
The android failure should be a bug? |
d53724d to
afc0f86
Compare
|
@llvm/pr-subscribers-libcxx Author: Hristo Hristov (H-G-Hristov) Changes
Full diff: https://github.com/llvm/llvm-project/pull/172008.diff 3 Files Affected:
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 670b90fc7b3b9..e02e45f425f4f 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -1113,28 +1113,32 @@ swap(const tuple<_Tp...>& __lhs,
// get
template <size_t _Ip, class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+typename tuple_element<_Ip, tuple<_Tp...> >::type&
get(tuple<_Tp...>& __t) _NOEXCEPT {
using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
}
template <size_t _Ip, class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
get(const tuple<_Tp...>& __t) _NOEXCEPT {
using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
}
template <size_t _Ip, class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+typename tuple_element<_Ip, tuple<_Tp...> >::type&&
get(tuple<_Tp...>&& __t) _NOEXCEPT {
using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
return static_cast<type&&>(static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
}
template <size_t _Ip, class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
get(const tuple<_Tp...>&& __t) _NOEXCEPT {
using type _LIBCPP_NODEBUG = typename tuple_element<_Ip, tuple<_Tp...> >::type;
return static_cast<const type&&>(static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
@@ -1143,22 +1147,22 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT {
# if _LIBCPP_STD_VER >= 14
template <class _T1, class... _Args>
-inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept {
return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
}
template <class _T1, class... _Args>
-inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept {
return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
}
template <class _T1, class... _Args>
-inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept {
return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup));
}
template <class _T1, class... _Args>
-inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept {
return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup));
}
@@ -1167,18 +1171,19 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(tuple<_Args...> const&& _
// tie
template <class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_Tp&... __t) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_Tp&... __t) _NOEXCEPT {
return tuple<_Tp&...>(__t...);
}
template <class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<__unwrap_ref_decay_t<_Tp>...>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<__unwrap_ref_decay_t<_Tp>...>
make_tuple(_Tp&&... __t) {
return tuple<__unwrap_ref_decay_t<_Tp>...>(std::forward<_Tp>(__t)...);
}
template <class... _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...> forward_as_tuple(_Tp&&... __t) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...>
+forward_as_tuple(_Tp&&... __t) _NOEXCEPT {
return tuple<_Tp&&...>(std::forward<_Tp>(__t)...);
}
@@ -1300,7 +1305,7 @@ template <class... _Tuples>
using __tuple_cat_return_t _LIBCPP_NODEBUG =
typename __tuple_cat_return_impl<tuple<>, __remove_cvref_t<_Tuples>...>::type;
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<> tuple_cat() { return tuple<>(); }
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<> tuple_cat() { return tuple<>(); }
template <class _Rp, class _Indices, class _Tuple0, class... _Tuples>
struct __tuple_cat_return_ref_imp;
@@ -1368,7 +1373,7 @@ __tuple_cat_select_element_wise(_TupleSrc&& __src, __index_sequence<_Indices...>
}
template <class _Tuple0, class... _Tuples>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_cat_return_t<_Tuple0, _Tuples...>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __tuple_cat_return_t<_Tuple0, _Tuples...>
tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) {
using _T0 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple0>;
using _TRet _LIBCPP_NODEBUG = __tuple_cat_return_t<_Tuple0, _Tuples...>;
@@ -1435,7 +1440,7 @@ template <class _Tp, class _Tuple>
template <class _Tp, class _Tuple, class = enable_if_t<__can_make_from_tuple<_Tp, _Tuple>>> // strengthen
#endif // _LIBCPP_STD_VER >= 20
-inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
noexcept(noexcept(std::__make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))) {
#if _LIBCPP_STD_VER >= 23
diff --git a/libcxx/test/libcxx/utilities/tuple/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/tuple/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..6ca7310bab771
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/tuple/nodiscard.verify.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++11
+
+// Check that functions are marked [[nodiscard]]
+
+#include <tuple>
+
+#include "test_macros.h"
+
+void test() {
+ struct First {};
+ struct Second {};
+ struct Third {};
+
+ std::tuple<First, Second, Third> t;
+ const std::tuple<First, Second, Third> ct;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<0>(t);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<0>(ct);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<0>(std::move(t));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<0>(std::move(t));
+#if TEST_STD_VER >= 14
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<Third>(t);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<Third>(ct);
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<Third>(std::move(t));
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get<Third>(std::move(t));
+#endif
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::tie(ct);
+
+ First e1;
+ Second e2;
+ Third e3;
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_tuple(e1, e2, e3);
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::forward_as_tuple(First{}, Second{}, Third{});
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::tuple_cat(std::tuple<First>{}, std::tuple<Second, Third>{});
+
+#if TEST_STD_VER >= 17
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_from_tuple<First>(std::tuple<First>{});
+#endif
+}
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/recursion_depth.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/recursion_depth.pass.cpp
index 57d37079c9f0c..ed44344edd0ad 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/recursion_depth.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/recursion_depth.pass.cpp
@@ -22,8 +22,10 @@ constexpr void CreateTuple(std::index_sequence<I...>) {
using LargeTuple = std::tuple<std::integral_constant<std::size_t, I>...>;
using TargetTuple = std::tuple<decltype(I)...>;
LargeTuple tuple(std::integral_constant<std::size_t, I>{}...);
- assert(std::get<0>(tuple).value == 0);
- assert(std::get<sizeof...(I)-1>(tuple).value == sizeof...(I)-1);
+ auto e1 = std::get<0>(tuple);
+ assert(e1.value == 0);
+ auto e2 = std::get<sizeof...(I) - 1>(tuple);
+ assert(e2.value == sizeof...(I) - 1);
TargetTuple t1 = tuple; // converting copy constructor from &
TargetTuple t2 = static_cast<LargeTuple const&>(tuple); // converting copy constructor from const&
|
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. - https://libcxx.llvm.org/CodingGuidelines.html - https://wg21.link/tuple
afc0f86 to
80c248b
Compare
[[nodiscard]]should be applied to functions where discarding the return value is most likely a correctness issue.