[libcxx-commits] [libcxx] [libc++] Applied `[[nodiscard]]` to more Language Support classes (PR #171078)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Dec 9 21:53:52 PST 2025
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/171078
>From 4936b77d8dc504c8974205e4354bc030f1c4c7ff Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 8 Dec 2025 06:48:15 +0200
Subject: [PATCH] [libc++] Applied `[[nodiscard]]` to more Language Support
classes
[[nodiscard]] should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
---
libcxx/include/__new/exceptions.h | 4 +-
libcxx/include/typeindex | 8 +--
libcxx/include/typeinfo | 21 ++++----
.../diagnostics/new.nodiscard.verify.cpp | 50 +++++++++++++------
.../language.support/nodiscard.verify.cpp | 33 ++++++++++++
libcxx/test/support/test_macros.h | 4 ++
6 files changed, 92 insertions(+), 28 deletions(-)
diff --git a/libcxx/include/__new/exceptions.h b/libcxx/include/__new/exceptions.h
index 483e5e3811182..1aadc23120cbb 100644
--- a/libcxx/include/__new/exceptions.h
+++ b/libcxx/include/__new/exceptions.h
@@ -32,7 +32,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_alloc : public exception {
_LIBCPP_HIDE_FROM_ABI bad_alloc(const bad_alloc&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_alloc& operator=(const bad_alloc&) _NOEXCEPT = default;
~bad_alloc() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length : public bad_alloc {
@@ -41,7 +41,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length : public bad_alloc {
_LIBCPP_HIDE_FROM_ABI bad_array_new_length(const bad_array_new_length&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_array_new_length& operator=(const bad_array_new_length&) _NOEXCEPT = default;
~bad_array_new_length() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
diff --git a/libcxx/include/typeindex b/libcxx/include/typeindex
index e32cb074318b6..82ea3d616f35d 100644
--- a/libcxx/include/typeindex
+++ b/libcxx/include/typeindex
@@ -86,8 +86,8 @@ public:
}
# endif
- _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __t_->hash_code(); }
- _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __t_->hash_code(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
};
template <class _Tp>
@@ -95,7 +95,9 @@ struct hash;
template <>
struct hash<type_index> : public __unary_function<type_index, size_t> {
- _LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT { return __index.hash_code(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT {
+ return __index.hash_code();
+ }
};
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo
index f608c94d3031e..f67d61e368087 100644
--- a/libcxx/include/typeinfo
+++ b/libcxx/include/typeinfo
@@ -95,11 +95,13 @@ class _LIBCPP_EXPORTED_FROM_ABI type_info {
public:
virtual ~type_info();
- const char* name() const _NOEXCEPT;
+ [[__nodiscard__]] const char* name() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT { return __compare(__arg) < 0; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
+ return __compare(__arg) < 0;
+ }
- size_t hash_code() const _NOEXCEPT;
+ [[__nodiscard__]] size_t hash_code() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
// When evaluated in a constant expression, both type infos simply can't come
@@ -306,14 +308,15 @@ protected:
public:
virtual ~type_info();
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT {
+ return __impl::__type_name_to_string(__type_name);
+ }
- _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __impl::__type_name_to_string(__type_name); }
-
- _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
return __impl::__lt(__type_name, __arg.__type_name);
}
- _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
// When evaluated in a constant expression, both type infos simply can't come
@@ -336,7 +339,7 @@ public:
_LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_cast& operator=(const bad_cast&) _NOEXCEPT = default;
~bad_cast() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
class _LIBCPP_EXPORTED_FROM_ABI bad_typeid : public exception {
@@ -345,7 +348,7 @@ public:
_LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_typeid& operator=(const bad_typeid&) _NOEXCEPT = default;
~bad_typeid() _NOEXCEPT override;
- const char* what() const _NOEXCEPT override;
+ [[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
} // namespace std
diff --git a/libcxx/test/libcxx/diagnostics/new.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/new.nodiscard.verify.cpp
index 505618c0b88d7..bd5b9dd001a11 100644
--- a/libcxx/test/libcxx/diagnostics/new.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/new.nodiscard.verify.cpp
@@ -6,30 +6,52 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03
+// <new>
-// check that <array> functions are marked [[nodiscard]]
-
-// clang-format off
+// Check that functions are marked [[nodiscard]]
#include <new>
#include "test_macros.h"
void test() {
- ::operator new(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- ::operator new(0, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- ::operator new[](0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- ::operator new[](0, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ {
+ std::bad_alloc ex;
+
+ ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+ {
+ std::bad_array_new_length ex;
+
+ ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ {
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(0);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(0, std::nothrow);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0, std::nothrow);
#if _LIBCPP_HAS_ALIGNED_ALLOCATION
- ::operator new(0, std::align_val_t{1}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- ::operator new(0, std::align_val_t{1}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- ::operator new[](0, std::align_val_t{1}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- ::operator new[](0, std::align_val_t{1}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(0, std::align_val_t{1});
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(0, std::align_val_t{1}, std::nothrow);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0, std::align_val_t{1});
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0, std::align_val_t{1}, std::nothrow);
#endif // _LIBCPP_HAS_ALIGNED_ALLOCATION
+ }
#if TEST_STD_VER >= 17
- int* ptr = nullptr;
- std::launder(ptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ {
+ int* ptr = nullptr;
+
+ std::launder(ptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
#endif
}
diff --git a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
index eeadd9f545538..6d784f27440e1 100644
--- a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
@@ -16,6 +16,8 @@
#include <coroutine>
#include <exception>
#include <initializer_list>
+#include <typeinfo>
+#include <typeindex>
#include "test_macros.h"
@@ -126,4 +128,35 @@ void test() {
il.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
#endif
+
+#if !defined(TEST_HAS_NO_RTTI)
+ { // <typeindex>
+ const std::type_index ti(typeid(int));
+
+ ti.hash_code(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ti.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::hash<std::type_index> hash;
+
+ hash(ti); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#endif
+
+#if !defined(TEST_HAS_NO_RTTI)
+ { // <typeinfo>
+ const std::type_info& ti = typeid(int);
+
+ ti.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ti.before(ti); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ti.hash_code(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ const std::bad_cast bc;
+
+ bc.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ const std::bad_typeid bt;
+
+ bc.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+#endif
}
diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 8d88d6fad7d0b..f75dfbfa6ada5 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -230,6 +230,10 @@
# define TEST_HAS_NO_ALIGNED_ALLOCATION
#endif
+#if !defined(_LIBCPP_ABI_VCRUNTIME)
+# define TEST_HAS_NO_ABI_VCRUNTIME
+#endif
+
#if TEST_STD_VER > 17
# define TEST_CONSTINIT constinit
#elif __has_cpp_attribute(clang::require_constant_initialization)
More information about the libcxx-commits
mailing list