[libcxx-commits] [libcxx] [libc++][memory] Applied `[[nodiscard]]` to more functions (PR #172131)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jan 7 09:24:38 PST 2026


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/172131

>From bcfa3216ce2f7db3b806b04fdc1bb65c834ba555 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 13 Dec 2025 08:14:12 +0200
Subject: [PATCH 1/7] [libc+] Applied `[[nodiscard]]` to Allocators

Towards #172124
---
 libcxx/include/__memory/addressof.h           | 12 ++--
 libcxx/include/__memory/allocator.h           |  7 +-
 .../__memory/is_sufficiently_aligned.h        |  2 +-
 .../include/__memory/raw_storage_iterator.h   |  2 +-
 .../diagnostics/memory.nodiscard.verify.cpp   | 66 +++++++++++++------
 5 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/libcxx/include/__memory/addressof.h b/libcxx/include/__memory/addressof.h
index 667071dfc6635..52ec94a5299fa 100644
--- a/libcxx/include/__memory/addressof.h
+++ b/libcxx/include/__memory/addressof.h
@@ -19,7 +19,8 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-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 <class _Tp>
-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 <class _Tp>
-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 <class _Tp>
-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 <class _Tp>
-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 1c96a2ab64578..609b305a1250f 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -120,10 +120,11 @@ class allocator
     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 @@ class allocator
     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/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
index 4280920cabb4b..93d24aaf78f0b 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 <size_t _Alignment, class _Tp>
-_LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
   return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
 }
 
diff --git a/libcxx/include/__memory/raw_storage_iterator.h b/libcxx/include/__memory/raw_storage_iterator.h
index d98b3faf48468..7c9b34076de46 100644
--- a/libcxx/include/__memory/raw_storage_iterator.h
+++ b/libcxx/include/__memory/raw_storage_iterator.h
@@ -67,7 +67,7 @@ class _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
     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 6410c84e926aa..e4e753822688a 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -6,37 +6,65 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03
+// <memory>
 
-// check that <memory> 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 <memory>
 
 #include "test_macros.h"
 
 void test() {
-  std::get_temporary_buffer<int>(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}
+  int i = 0;
 
-void test_allocator_traits() {
-  std::allocator<int> allocator;
-  std::allocator_traits<std::allocator<int>> 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}}
-}
+  {
+    std::addressof(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::get_temporary_buffer<int>(0);
+#if _LIBCPP_STD_VER >= 26
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    std::is_sufficiently_aligned<2>(&i);
+#endif
+  }
 
-void test_allocator() {
   std::allocator<int> 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}}
-#endif
+
+  {
+    std::allocator_traits<std::allocator<int> > allocator_traits;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    allocator_traits.allocate(allocator, 1);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    allocator_traits.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 at +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}}
+    allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    // expected-warning at +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 // TEST_STD_VER <= 17
+
+#if TEST_STD_VER >= 14
+  {
+    std::raw_storage_iterator<int*, int> it{nullptr};
+
+    it.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  }
 #endif
-}
+}
\ No newline at end of file

>From 55cd9bcef7b1257a028bdd6e791ffb7ec5f1420a Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 3 Jan 2026 18:14:51 +0200
Subject: [PATCH 2/7] Addressed review comments

---
 libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index e4e753822688a..e9f72e65a98ac 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -42,6 +42,8 @@ void test() {
     allocator_traits.allocate(allocator, 1, nullptr);
   }
 
+  allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
 #if TEST_STD_VER >= 23
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   allocator.allocate_at_least(1);
@@ -53,7 +55,7 @@ void test() {
 
     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}}
-    allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
     // expected-warning at +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}}

>From b569578253a8bd7cb7f746e8ed4bef3e0fcf88b3 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 6 Jan 2026 14:09:02 +0200
Subject: [PATCH 3/7] Addressed review comments

---
 libcxx/include/__memory/allocator_traits.h    |  6 +-
 .../include/__memory/raw_storage_iterator.h   |  2 +-
 .../diagnostics/memory.nodiscard.verify.cpp   | 57 ++++++++++++++++---
 .../allocate.verify.cpp                       | 34 -----------
 4 files changed, 53 insertions(+), 46 deletions(-)
 delete mode 100644 libcxx/test/std/utilities/memory/allocator.traits/allocator.traits.members/allocate.verify.cpp

diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index 46c247f7040e0..c389c1d057b89 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -314,13 +314,15 @@ struct allocator_traits {
   }
 
   template <class _Ap = _Alloc, __enable_if_t<__has_max_size_v<const _Ap>, 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 <class _Ap = _Alloc, __enable_if_t<!__has_max_size_v<const _Ap>, 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<size_type>::max() / sizeof(value_type);
   }
 
diff --git a/libcxx/include/__memory/raw_storage_iterator.h b/libcxx/include/__memory/raw_storage_iterator.h
index 7c9b34076de46..dff0fed3b7565 100644
--- a/libcxx/include/__memory/raw_storage_iterator.h
+++ b/libcxx/include/__memory/raw_storage_iterator.h
@@ -46,7 +46,7 @@ class _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
   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;
diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index e9f72e65a98ac..6ff0f152d85e3 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -31,26 +31,64 @@ void test() {
 #endif
   }
 
-  std::allocator<int> allocator;
-
   {
-    std::allocator_traits<std::allocator<int> > allocator_traits;
+    struct Alloc {
+      typedef int value_type;
+
+      value_type* allocate(std::size_t n);
+      value_type* allocate(std::size_t n, const void* p);
+    } allocator;
+    typedef std::allocator_traits<Alloc> AllocTraits;
+
+    struct HintedAlloc {
+      typedef int value_type;
+      typedef const void* const_void_pointer;
 
+      value_type* allocate(std::size_t n);
+      value_type* allocate(std::size_t n, const void* p);
+    } hintedAllocator;
+    typedef std::allocator_traits<HintedAlloc> HintedAllocTraits;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    AllocTraits::allocate(allocator, 1);
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    allocator_traits.allocate(allocator, 1);
+    HintedAllocTraits::allocate(hintedAllocator, 1);
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    allocator_traits.allocate(allocator, 1, nullptr);
+    AllocTraits::allocate(allocator, 1, nullptr);
+
+#if TEST_STD_VER >= 23
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    AllocTraits::allocate_at_least(allocator, 1, nullptr);
+#endif
+
+    struct SizedAlloc {
+      typedef int value_type;
+      typedef std::size_t size_type;
+
+      value_type* allocate(std::size_t n);
+      value_type* allocate(std::size_t n, const void* p);
+      size_type max_size();
+    } sizedAllocator;
+    typedef std::allocator_traits<SizedAlloc> SizedAllocTraits;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    SizedAllocTraits::max_size(sizedAllocator);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    AllocTraits::max_size(allocator);
   }
 
-  allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  {
+    std::allocator<int> allocator;
+
+    allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 
 #if TEST_STD_VER >= 23
-  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-  allocator.allocate_at_least(1);
+    // expected-warning at +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}}
@@ -66,6 +104,7 @@ void test() {
   {
     std::raw_storage_iterator<int*, int> 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 adb4d697e1324..0000000000000
--- 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
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// template <class Alloc>
-// struct allocator_traits
-// {
-//     static constexpr pointer allocate(allocator_type& a, size_type n);
-//     ...
-// };
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-#include <cstddef>
-#include <memory>
-
-template <class T>
-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<int> a;
-    std::allocator_traits<A<int> >::allocate(a, 10);          // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    std::allocator_traits<A<int> >::allocate(a, 10, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

>From 2698553d0f9b39e2c91453e89f6eec795a8c0231 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 6 Jan 2026 14:37:52 +0200
Subject: [PATCH 4/7] Updated `allocator_traits.h` with `[[nodiscard]]`

---
 libcxx/include/__memory/allocator_traits.h    |  4 +--
 .../diagnostics/memory.nodiscard.verify.cpp   | 36 +++++++++++++------
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index c389c1d057b89..b38d7293a3fd3 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -327,12 +327,12 @@ struct allocator_traits {
   }
 
   template <class _Ap = _Alloc, __enable_if_t<__has_select_on_container_copy_construction_v<const _Ap>, 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 <class _Ap = _Alloc, __enable_if_t<!__has_select_on_container_copy_construction_v<const _Ap>, 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/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index 6ff0f152d85e3..9bd33d4818014 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -35,8 +35,8 @@ void test() {
     struct Alloc {
       typedef int value_type;
 
-      value_type* allocate(std::size_t n);
-      value_type* allocate(std::size_t n, const void* p);
+      value_type* allocate(std::size_t) { return nullptr; }
+      value_type* allocate(std::size_t, const void*) { return nullptr; }
     } allocator;
     typedef std::allocator_traits<Alloc> AllocTraits;
 
@@ -44,8 +44,8 @@ void test() {
       typedef int value_type;
       typedef const void* const_void_pointer;
 
-      value_type* allocate(std::size_t n);
-      value_type* allocate(std::size_t n, const void* p);
+      value_type* allocate(std::size_t) { return nullptr; }
+      value_type* allocate(std::size_t, const void*) { return nullptr; }
     } hintedAllocator;
     typedef std::allocator_traits<HintedAlloc> HintedAllocTraits;
 
@@ -58,15 +58,16 @@ void test() {
 
 #if TEST_STD_VER >= 23
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    AllocTraits::allocate_at_least(allocator, 1, nullptr);
+    AllocTraits::allocate_at_least(allocator, 1);
 #endif
 
     struct SizedAlloc {
       typedef int value_type;
       typedef std::size_t size_type;
 
-      value_type* allocate(std::size_t n);
-      value_type* allocate(std::size_t n, const void* p);
+      value_type* allocate(std::size_t) { return nullptr; }
+      value_type* allocate(std::size_t, const void*) { return nullptr; }
+
       size_type max_size();
     } sizedAllocator;
     typedef std::allocator_traits<SizedAlloc> SizedAllocTraits;
@@ -75,6 +76,22 @@ void test() {
     SizedAllocTraits::max_size(sizedAllocator);
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     AllocTraits::max_size(allocator);
+
+    struct SelectAlloc {
+      typedef int value_type;
+      typedef const void* const_void_pointer;
+
+      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;
+    typedef std::allocator_traits<SelectAlloc> SelectAllocTraits;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    SelectAllocTraits::select_on_container_copy_construction(selectAllocator);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    AllocTraits::select_on_container_copy_construction(allocator);
   }
 
   {
@@ -88,7 +105,6 @@ void test() {
 #endif
 
 #if TEST_STD_VER <= 17
-
     const int ci = 0;
 
     allocator.address(i);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -97,8 +113,8 @@ void test() {
     // expected-warning at +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
   }
-#endif // TEST_STD_VER <= 17
 
 #if TEST_STD_VER >= 14
   {
@@ -108,4 +124,4 @@ void test() {
     it.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
 #endif
-}
\ No newline at end of file
+}

>From 907feee70aca17353094eca4445021600b416a41 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 6 Jan 2026 14:43:08 +0200
Subject: [PATCH 5/7] Fixed test

---
 libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index 9bd33d4818014..f276291a61cf9 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -52,7 +52,7 @@ void test() {
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     AllocTraits::allocate(allocator, 1);
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
-    HintedAllocTraits::allocate(hintedAllocator, 1);
+    HintedAllocTraits::allocate(hintedAllocator, 1, nullptr);
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     AllocTraits::allocate(allocator, 1, nullptr);
 
@@ -68,7 +68,7 @@ void test() {
       value_type* allocate(std::size_t) { return nullptr; }
       value_type* allocate(std::size_t, const void*) { return nullptr; }
 
-      size_type max_size();
+      size_type max_size() const { return 0; }
     } sizedAllocator;
     typedef std::allocator_traits<SizedAlloc> SizedAllocTraits;
 

>From 66f91a4fee958f74d761199e70e5e3f4a68e6e15 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 6 Jan 2026 14:53:53 +0200
Subject: [PATCH 6/7] Final fix

---
 libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index f276291a61cf9..563c9c753e3a0 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -36,16 +36,16 @@ void test() {
       typedef int value_type;
 
       value_type* allocate(std::size_t) { return nullptr; }
-      value_type* allocate(std::size_t, const void*) { return nullptr; }
     } allocator;
     typedef std::allocator_traits<Alloc> AllocTraits;
 
     struct HintedAlloc {
       typedef int value_type;
+      typedef std::size_t size_type;
       typedef const void* const_void_pointer;
 
-      value_type* allocate(std::size_t) { return nullptr; }
-      value_type* allocate(std::size_t, const void*) { return nullptr; }
+      value_type* allocate(size_type) { return nullptr; }
+      value_type* allocate(size_type, const_void_pointer) { return nullptr; }
     } hintedAllocator;
     typedef std::allocator_traits<HintedAlloc> HintedAllocTraits;
 

>From fd283cdd64848673552eeebd5eb5a5bb679e6a61 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 7 Jan 2026 19:24:18 +0200
Subject: [PATCH 7/7] Use `using`

---
 .../diagnostics/memory.nodiscard.verify.cpp   | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
index 563c9c753e3a0..6bddeceb9951a 100644
--- a/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp
@@ -33,21 +33,21 @@ void test() {
 
   {
     struct Alloc {
-      typedef int value_type;
+      using value_type = int;
 
       value_type* allocate(std::size_t) { return nullptr; }
     } allocator;
-    typedef std::allocator_traits<Alloc> AllocTraits;
+    using AllocTraits = std::allocator_traits<Alloc>;
 
     struct HintedAlloc {
-      typedef int value_type;
-      typedef std::size_t size_type;
-      typedef const void* const_void_pointer;
+      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;
-    typedef std::allocator_traits<HintedAlloc> HintedAllocTraits;
+    using HintedAllocTraits = std::allocator_traits<HintedAlloc>;
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     AllocTraits::allocate(allocator, 1);
@@ -62,15 +62,15 @@ void test() {
 #endif
 
     struct SizedAlloc {
-      typedef int value_type;
-      typedef std::size_t size_type;
+      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;
-    typedef std::allocator_traits<SizedAlloc> SizedAllocTraits;
+    using SizedAllocTraits = std::allocator_traits<SizedAlloc>;
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     SizedAllocTraits::max_size(sizedAllocator);
@@ -78,15 +78,15 @@ void test() {
     AllocTraits::max_size(allocator);
 
     struct SelectAlloc {
-      typedef int value_type;
-      typedef const void* const_void_pointer;
+      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;
-    typedef std::allocator_traits<SelectAlloc> SelectAllocTraits;
+    using SelectAllocTraits = std::allocator_traits<SelectAlloc>;
 
     // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
     SelectAllocTraits::select_on_container_copy_construction(selectAllocator);



More information about the libcxx-commits mailing list