diff --git a/libcxx/include/__memory/addressof.h b/libcxx/include/__memory/addressof.h index 667071dfc663..52ec94a5299f 100644 --- a/libcxx/include/__memory/addressof.h +++ b/libcxx/include/__memory/addressof.h @@ -19,7 +19,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp* addressof(_Tp& __x) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp* +addressof(_Tp& __x) _NOEXCEPT { return __builtin_addressof(__x); } @@ -27,24 +28,25 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_NO_CFI _LIBCPP_HIDE_FROM_ABI _Tp* a // Objective-C++ Automatic Reference Counting uses qualified pointers // that require special addressof() signatures. template -inline _LIBCPP_HIDE_FROM_ABI __strong _Tp* addressof(__strong _Tp& __x) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __strong _Tp* addressof(__strong _Tp& __x) _NOEXCEPT { return &__x; } # if __has_feature(objc_arc_weak) template -inline _LIBCPP_HIDE_FROM_ABI __weak _Tp* addressof(__weak _Tp& __x) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __weak _Tp* addressof(__weak _Tp& __x) _NOEXCEPT { return &__x; } # endif template -inline _LIBCPP_HIDE_FROM_ABI __autoreleasing _Tp* addressof(__autoreleasing _Tp& __x) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __autoreleasing _Tp* addressof(__autoreleasing _Tp& __x) _NOEXCEPT { return &__x; } template -inline _LIBCPP_HIDE_FROM_ABI __unsafe_unretained _Tp* addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __unsafe_unretained _Tp* +addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT { return &__x; } #endif diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h index 1c96a2ab6457..609b305a1250 100644 --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -120,10 +120,11 @@ public: typedef allocator<_Up> other; }; - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI pointer address(reference __x) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI pointer address(reference __x) const _NOEXCEPT { return std::addressof(__x); } - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI const_pointer address(const_reference __x) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI const_pointer + address(const_reference __x) const _NOEXCEPT { return std::addressof(__x); } @@ -131,7 +132,7 @@ public: return allocate(__n); } - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return size_type(~0) / sizeof(_Tp); } diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h index 46c247f7040e..b38d7293a3fd 100644 --- a/libcxx/include/__memory/allocator_traits.h +++ b/libcxx/include/__memory/allocator_traits.h @@ -314,23 +314,25 @@ struct allocator_traits { } template , int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type max_size(const allocator_type& __a) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type + max_size(const allocator_type& __a) _NOEXCEPT { _LIBCPP_SUPPRESS_DEPRECATED_PUSH return __a.max_size(); _LIBCPP_SUPPRESS_DEPRECATED_POP } template , int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type max_size(const allocator_type&) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type + max_size(const allocator_type&) _NOEXCEPT { return numeric_limits::max() / sizeof(value_type); } template , int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type select_on_container_copy_construction(const allocator_type& __a) { return __a.select_on_container_copy_construction(); } template , int> = 0> - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type select_on_container_copy_construction(const allocator_type& __a) { return __a; } diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h index 4280920cabb4..93d24aaf78f0 100644 --- a/libcxx/include/__memory/is_sufficiently_aligned.h +++ b/libcxx/include/__memory/is_sufficiently_aligned.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 26 template -_LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) { return reinterpret_cast(__ptr) % _Alignment == 0; } diff --git a/libcxx/include/__memory/raw_storage_iterator.h b/libcxx/include/__memory/raw_storage_iterator.h index d98b3faf4846..dff0fed3b756 100644 --- a/libcxx/include/__memory/raw_storage_iterator.h +++ b/libcxx/include/__memory/raw_storage_iterator.h @@ -46,7 +46,7 @@ public: typedef void reference; _LIBCPP_HIDE_FROM_ABI explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {} - _LIBCPP_HIDE_FROM_ABI raw_storage_iterator& operator*() { return *this; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI raw_storage_iterator& operator*() { return *this; } _LIBCPP_HIDE_FROM_ABI raw_storage_iterator& operator=(const _Tp& __element) { ::new ((void*)std::addressof(*__x_)) _Tp(__element); return *this; @@ -67,7 +67,7 @@ public: return __t; } # if _LIBCPP_STD_VER >= 14 - _LIBCPP_HIDE_FROM_ABI _OutputIterator base() const { return __x_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _OutputIterator base() const { return __x_; } # endif }; diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp index 6410c84e926a..6bddeceb9951 100644 --- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp @@ -6,37 +6,122 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 +// -// check that functions are marked [[nodiscard]] +// Check that functions are marked [[nodiscard]] +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -// clang-format off - #include #include "test_macros.h" void test() { - std::get_temporary_buffer(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} + int i = 0; -void test_allocator_traits() { - std::allocator allocator; - std::allocator_traits> allocator_traits; - allocator_traits.allocate(allocator, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - allocator_traits.allocate(allocator, 1, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} - -void test_allocator() { - std::allocator allocator; - allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -#if TEST_STD_VER <= 17 - allocator.allocate(1, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + { + std::addressof(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get_temporary_buffer(0); +#if _LIBCPP_STD_VER >= 26 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::is_sufficiently_aligned<2>(&i); #endif + } + + { + struct Alloc { + using value_type = int; + + value_type* allocate(std::size_t) { return nullptr; } + } allocator; + using AllocTraits = std::allocator_traits; + + struct HintedAlloc { + using value_type = int; + using size_type = std::size_t; + using const_void_pointer = const void*; + + value_type* allocate(size_type) { return nullptr; } + value_type* allocate(size_type, const_void_pointer) { return nullptr; } + } hintedAllocator; + using HintedAllocTraits = std::allocator_traits; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + AllocTraits::allocate(allocator, 1); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + HintedAllocTraits::allocate(hintedAllocator, 1, nullptr); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + AllocTraits::allocate(allocator, 1, nullptr); + #if TEST_STD_VER >= 23 - allocator.allocate_at_least(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + AllocTraits::allocate_at_least(allocator, 1); +#endif + + struct SizedAlloc { + using value_type = int; + using size_type = std::size_t; + + value_type* allocate(std::size_t) { return nullptr; } + value_type* allocate(std::size_t, const void*) { return nullptr; } + + size_type max_size() const { return 0; } + } sizedAllocator; + using SizedAllocTraits = std::allocator_traits; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + SizedAllocTraits::max_size(sizedAllocator); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + AllocTraits::max_size(allocator); + + struct SelectAlloc { + using value_type = int; + using const_void_pointer = const void*; + + value_type* allocate(std::size_t) { return nullptr; } + value_type* allocate(std::size_t, const void*) { return nullptr; } + + SelectAlloc select_on_container_copy_construction() const { return SelectAlloc(); }; + } selectAllocator; + using SelectAllocTraits = std::allocator_traits; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + SelectAllocTraits::select_on_container_copy_construction(selectAllocator); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + AllocTraits::select_on_container_copy_construction(allocator); + } + + { + std::allocator allocator; + + allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if TEST_STD_VER >= 23 + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + allocator.allocate_at_least(1); +#endif + +#if TEST_STD_VER <= 17 + const int ci = 0; + + allocator.address(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + allocator.address(ci); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + allocator.allocate(1, nullptr); + allocator.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + } + +#if TEST_STD_VER >= 14 + { + std::raw_storage_iterator it{nullptr}; + + *it; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + it.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } #endif } diff --git a/libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.verify.cpp b/libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.verify.cpp deleted file mode 100644 index adb4d697e132..000000000000 --- a/libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.verify.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// - -// template -// struct allocator_traits -// { -// static constexpr pointer allocate(allocator_type& a, size_type n); -// ... -// }; - -// UNSUPPORTED: c++03, c++11, c++14, c++17 - -#include -#include - -template -struct A { - typedef T value_type; - value_type* allocate(std::size_t n); - value_type* allocate(std::size_t n, const void* p); -}; - -void f() { - A a; - std::allocator_traits >::allocate(a, 10); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::allocator_traits >::allocate(a, 10, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -}