diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h index f74f25fa6e84b..d81ff1abbdaba 100644 --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -435,7 +435,7 @@ struct hash : public __hash_impl<_Tp> {}; template <> struct hash : public __unary_function { - _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } }; #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index 6eddc4daa4184..4fbd0af98463e 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -77,7 +77,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception { _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default; _LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default; ~bad_weak_ptr() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; + [[__nodiscard__]] const char* what() const _NOEXCEPT override; }; [[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() { @@ -1423,7 +1423,7 @@ struct hash > { _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; #endif - _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT { return hash::element_type*>()(__ptr.get()); } }; diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h index b5f469365daed..6a4ec0a466ba7 100644 --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -800,7 +800,7 @@ struct hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; #endif - _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; return hash()(__ptr.get()); } diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h index fe8773ab73165..9450d526ed32c 100644 --- a/libcxx/include/__utility/integer_sequence.h +++ b/libcxx/include/__utility/integer_sequence.h @@ -33,7 +33,7 @@ template struct __integer_sequence { using value_type = _Tp; static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type"); - static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); } + [[__nodiscard__]] static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Indices); } }; template diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 955a7cc3e364a..bbc2617835bc0 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1661,7 +1661,10 @@ module std [system] { } module raw_storage_iterator { header "__memory/raw_storage_iterator.h" } module shared_count { header "__memory/shared_count.h" } - module shared_ptr { header "__memory/shared_ptr.h" } + module shared_ptr { + header "__memory/shared_ptr.h" + export std.functional.hash + } module swap_allocator { header "__memory/swap_allocator.h" } module temp_value { header "__memory/temp_value.h" } module temporary_buffer { @@ -1674,6 +1677,7 @@ module std [system] { } module unique_ptr { header "__memory/unique_ptr.h" + export std.functional.hash } module unique_temporary_buffer { header "__memory/unique_temporary_buffer.h" @@ -2392,6 +2396,7 @@ module std [system] { header "coroutine" export * + export std.functional.hash } } // module std diff --git a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp index 898b2ac06e3f2..521870f2484a2 100644 --- a/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/functional.nodiscard.verify.cpp @@ -10,6 +10,7 @@ // check that functions are marked [[nodiscard]] +#include #include #include "test_macros.h" @@ -59,4 +60,9 @@ void test() { std::ref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} std::cref(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // Hash specializations + + std::hash hash; + hash(nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp index 40dbe5c90afee..eeadd9f545538 100644 --- a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "test_macros.h" diff --git a/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp new file mode 100644 index 0000000000000..4ca52ace08dd3 --- /dev/null +++ b/libcxx/test/libcxx/utilities/intseq/nodiscard.verify.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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++14 + +// + +// Check that functions are marked [[nodiscard]] + +#include + +void test() { + std::integer_sequence seq; + + seq.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp index 66e00d6fa66c0..6e713fe5217ba 100644 --- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp @@ -41,6 +41,14 @@ void test() { // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::make_unique_for_overwrite(5); #endif + + std::hash> hash; + hash(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // [util.smartptr.weak.bad] + std::bad_weak_ptr bwp; + + bwp.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } { // [util.sharedptr] std::shared_ptr sPtr; @@ -118,6 +126,9 @@ void test() { // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::get_deleter(sPtr); #endif + + std::hash> hash; + hash(sPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } { // [util.smartptr.weak] std::weak_ptr wPtr;