Skip to content

Commit 4936b77

Browse files
committed
[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
1 parent 4125e73 commit 4936b77

File tree

6 files changed

+92
-28
lines changed

6 files changed

+92
-28
lines changed

libcxx/include/__new/exceptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_alloc : public exception {
3232
_LIBCPP_HIDE_FROM_ABI bad_alloc(const bad_alloc&) _NOEXCEPT = default;
3333
_LIBCPP_HIDE_FROM_ABI bad_alloc& operator=(const bad_alloc&) _NOEXCEPT = default;
3434
~bad_alloc() _NOEXCEPT override;
35-
const char* what() const _NOEXCEPT override;
35+
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
3636
};
3737

3838
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 {
4141
_LIBCPP_HIDE_FROM_ABI bad_array_new_length(const bad_array_new_length&) _NOEXCEPT = default;
4242
_LIBCPP_HIDE_FROM_ABI bad_array_new_length& operator=(const bad_array_new_length&) _NOEXCEPT = default;
4343
~bad_array_new_length() _NOEXCEPT override;
44-
const char* what() const _NOEXCEPT override;
44+
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
4545
};
4646

4747
#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME

libcxx/include/typeindex

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,18 @@ public:
8686
}
8787
# endif
8888

89-
_LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __t_->hash_code(); }
90-
_LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
89+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __t_->hash_code(); }
90+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
9191
};
9292

9393
template <class _Tp>
9494
struct hash;
9595

9696
template <>
9797
struct hash<type_index> : public __unary_function<type_index, size_t> {
98-
_LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT { return __index.hash_code(); }
98+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT {
99+
return __index.hash_code();
100+
}
99101
};
100102

101103
_LIBCPP_END_NAMESPACE_STD

libcxx/include/typeinfo

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,13 @@ class _LIBCPP_EXPORTED_FROM_ABI type_info {
9595
public:
9696
virtual ~type_info();
9797

98-
const char* name() const _NOEXCEPT;
98+
[[__nodiscard__]] const char* name() const _NOEXCEPT;
9999

100-
_LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT { return __compare(__arg) < 0; }
100+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
101+
return __compare(__arg) < 0;
102+
}
101103

102-
size_t hash_code() const _NOEXCEPT;
104+
[[__nodiscard__]] size_t hash_code() const _NOEXCEPT;
103105

104106
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
105107
// When evaluated in a constant expression, both type infos simply can't come
@@ -306,14 +308,15 @@ protected:
306308

307309
public:
308310
virtual ~type_info();
311+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT {
312+
return __impl::__type_name_to_string(__type_name);
313+
}
309314

310-
_LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __impl::__type_name_to_string(__type_name); }
311-
312-
_LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
315+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool before(const type_info& __arg) const _NOEXCEPT {
313316
return __impl::__lt(__type_name, __arg.__type_name);
314317
}
315318

316-
_LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); }
319+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); }
317320

318321
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT {
319322
// When evaluated in a constant expression, both type infos simply can't come
@@ -336,7 +339,7 @@ public:
336339
_LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default;
337340
_LIBCPP_HIDE_FROM_ABI bad_cast& operator=(const bad_cast&) _NOEXCEPT = default;
338341
~bad_cast() _NOEXCEPT override;
339-
const char* what() const _NOEXCEPT override;
342+
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
340343
};
341344

342345
class _LIBCPP_EXPORTED_FROM_ABI bad_typeid : public exception {
@@ -345,7 +348,7 @@ public:
345348
_LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default;
346349
_LIBCPP_HIDE_FROM_ABI bad_typeid& operator=(const bad_typeid&) _NOEXCEPT = default;
347350
~bad_typeid() _NOEXCEPT override;
348-
const char* what() const _NOEXCEPT override;
351+
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
349352
};
350353

351354
} // namespace std

libcxx/test/libcxx/diagnostics/new.nodiscard.verify.cpp

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,52 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: c++03
9+
// <new>
1010

11-
// check that <array> functions are marked [[nodiscard]]
12-
13-
// clang-format off
11+
// Check that functions are marked [[nodiscard]]
1412

1513
#include <new>
1614

1715
#include "test_macros.h"
1816

1917
void test() {
20-
::operator new(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
21-
::operator new(0, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
22-
::operator new[](0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
23-
::operator new[](0, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
18+
{
19+
std::bad_alloc ex;
20+
21+
ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
22+
}
23+
{
24+
std::bad_array_new_length ex;
25+
26+
ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
27+
}
28+
29+
{
30+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
31+
::operator new(0);
32+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
33+
::operator new(0, std::nothrow);
34+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
35+
::operator new[](0);
36+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
37+
::operator new[](0, std::nothrow);
2438
#if _LIBCPP_HAS_ALIGNED_ALLOCATION
25-
::operator new(0, std::align_val_t{1}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
26-
::operator new(0, std::align_val_t{1}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
27-
::operator new[](0, std::align_val_t{1}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
28-
::operator new[](0, std::align_val_t{1}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
39+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
40+
::operator new(0, std::align_val_t{1});
41+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
42+
::operator new(0, std::align_val_t{1}, std::nothrow);
43+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
44+
::operator new[](0, std::align_val_t{1});
45+
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
46+
::operator new[](0, std::align_val_t{1}, std::nothrow);
2947
#endif // _LIBCPP_HAS_ALIGNED_ALLOCATION
48+
}
3049

3150
#if TEST_STD_VER >= 17
32-
int* ptr = nullptr;
33-
std::launder(ptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
51+
{
52+
int* ptr = nullptr;
53+
54+
std::launder(ptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
55+
}
3456
#endif
3557
}

libcxx/test/libcxx/language.support/nodiscard.verify.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <coroutine>
1717
#include <exception>
1818
#include <initializer_list>
19+
#include <typeinfo>
20+
#include <typeindex>
1921

2022
#include "test_macros.h"
2123

@@ -126,4 +128,35 @@ void test() {
126128
il.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
127129
}
128130
#endif
131+
132+
#if !defined(TEST_HAS_NO_RTTI)
133+
{ // <typeindex>
134+
const std::type_index ti(typeid(int));
135+
136+
ti.hash_code(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
137+
ti.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
138+
139+
std::hash<std::type_index> hash;
140+
141+
hash(ti); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
142+
}
143+
#endif
144+
145+
#if !defined(TEST_HAS_NO_RTTI)
146+
{ // <typeinfo>
147+
const std::type_info& ti = typeid(int);
148+
149+
ti.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
150+
ti.before(ti); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
151+
ti.hash_code(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
152+
153+
const std::bad_cast bc;
154+
155+
bc.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
156+
157+
const std::bad_typeid bt;
158+
159+
bc.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
160+
}
161+
#endif
129162
}

libcxx/test/support/test_macros.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@
230230
# define TEST_HAS_NO_ALIGNED_ALLOCATION
231231
#endif
232232

233+
#if !defined(_LIBCPP_ABI_VCRUNTIME)
234+
# define TEST_HAS_NO_ABI_VCRUNTIME
235+
#endif
236+
233237
#if TEST_STD_VER > 17
234238
# define TEST_CONSTINIT constinit
235239
#elif __has_cpp_attribute(clang::require_constant_initialization)

0 commit comments

Comments
 (0)