1// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-use-nodiscard %t -- \
2// RUN: -config="{CheckOptions: {modernize-use-nodiscard.ReplacementString: 'NO_DISCARD'}}"
3
4namespace std {
5template <class>
6class function;
7class string {};
8}
9
10namespace boost {
11template <class>
12class function;
13}
14
15#define MUST_USE_RESULT __attribute__((warn_unused_result))
16#define NO_DISCARD [[nodiscard]]
17#define NO_RETURN [[noreturn]]
18
19#define BOOLEAN_FUNC bool f23() const
20
21typedef unsigned my_unsigned;
22typedef unsigned &my_unsigned_reference;
23typedef const unsigned &my_unsigned_const_reference;
24
25struct NO_DISCARD NoDiscardStruct{};
26
27class Foo {
28public:
29 using size_type = unsigned;
30
31 bool f1() const;
32 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked NO_DISCARD [modernize-use-nodiscard]
33 // CHECK-FIXES: NO_DISCARD bool f1() const;
34
35 bool f2(int) const;
36 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked NO_DISCARD [modernize-use-nodiscard]
37 // CHECK-FIXES: NO_DISCARD bool f2(int) const;
38
39 bool f3(const int &) const;
40 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked NO_DISCARD [modernize-use-nodiscard]
41 // CHECK-FIXES: NO_DISCARD bool f3(const int &) const;
42
43 bool f4(void) const;
44 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked NO_DISCARD [modernize-use-nodiscard]
45 // CHECK-FIXES: NO_DISCARD bool f4(void) const;
46
47 // negative tests
48
49 void f5() const;
50
51 bool f6();
52
53 bool f7(int &);
54
55 bool f8(int &) const;
56
57 bool f9(int *) const;
58
59 bool f10(const int &, int &) const;
60
61 NO_DISCARD bool f12() const;
62
63 MUST_USE_RESULT bool f13() const;
64
65 [[nodiscard]] bool f11() const;
66
67 [[clang::warn_unused_result]] bool f11a() const;
68
69 [[gnu::warn_unused_result]] bool f11b() const;
70
71 bool _f20() const;
72 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function '_f20' should be marked NO_DISCARD [modernize-use-nodiscard]
73 // CHECK-FIXES: NO_DISCARD bool _f20() const;
74
75 NO_RETURN bool f21() const;
76
77 ~Foo();
78
79 bool operator+=(int) const;
80
81 // extra keywords (virtual,inline,const) on return type
82
83 virtual bool f14() const;
84 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f14' should be marked NO_DISCARD [modernize-use-nodiscard]
85 // CHECK-FIXES: NO_DISCARD virtual bool f14() const;
86
87 const bool f15() const;
88 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f15' should be marked NO_DISCARD [modernize-use-nodiscard]
89 // CHECK-FIXES: NO_DISCARD const bool f15() const;
90
91 inline const bool f16() const;
92 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f16' should be marked NO_DISCARD [modernize-use-nodiscard]
93 // CHECK-FIXES: NO_DISCARD inline const bool f16() const;
94
95 inline const std::string &f45() const;
96 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f45' should be marked NO_DISCARD [modernize-use-nodiscard]
97 // CHECK-FIXES: NO_DISCARD inline const std::string &f45() const;
98
99 inline virtual const bool f17() const;
100 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f17' should be marked NO_DISCARD [modernize-use-nodiscard]
101 // CHECK-FIXES: NO_DISCARD inline virtual const bool f17() const;
102
103 // inline with body
104 bool f18() const
105 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f18' should be marked NO_DISCARD [modernize-use-nodiscard]
106 // CHECK-FIXES: NO_DISCARD bool f18() const
107 {
108 return true;
109 }
110
111 bool f19() const;
112 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f19' should be marked NO_DISCARD [modernize-use-nodiscard]
113 // CHECK-FIXES: NO_DISCARD bool f19() const;
114
115 BOOLEAN_FUNC;
116
117 bool f24(size_type) const;
118 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f24' should be marked NO_DISCARD [modernize-use-nodiscard]
119 // CHECK-FIXES: NO_DISCARD bool f24(size_type) const;
120
121 bool f28(my_unsigned) const;
122 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f28' should be marked NO_DISCARD [modernize-use-nodiscard]
123 // CHECK-FIXES: NO_DISCARD bool f28(my_unsigned) const;
124
125 bool f29(my_unsigned_reference) const;
126
127 bool f30(my_unsigned_const_reference) const;
128 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f30' should be marked NO_DISCARD [modernize-use-nodiscard]
129 // CHECK-FIXES: NO_DISCARD bool f30(my_unsigned_const_reference) const;
130
131 template <class F>
132 F f37(F a, F b) const;
133
134 template <class F>
135 bool f38(F a) const;
136
137 bool f39(const std::function<bool()> &predicate) const;
138
139 bool f39a(std::function<bool()> predicate) const;
140
141 bool f39b(const std::function<bool()> predicate) const;
142
143 bool f45(const boost::function<bool()> &predicate) const;
144
145 bool f45a(boost::function<bool()> predicate) const;
146
147 bool f45b(const boost::function<bool()> predicate) const;
148
149 // Do not add ``[[nodiscard]]`` to parameter packs.
150 template <class... Args>
151 bool ParameterPack(Args... args) const;
152
153 template <typename... Targs>
154 bool ParameterPack2(Targs... Fargs) const;
155
156 // Do not add ``[[nodiscard]]`` to variadic functions.
157 bool VariadicFunctionTest(const int &, ...) const;
158
159 // Do not add ``[[nodiscard]]`` to non constant static functions.
160 static bool not_empty();
161
162 // Do not add ``[[nodiscard]]`` to conversion functions.
163 // explicit operator bool() const { return true; }
164
165 // Do not add ``[[nodiscard]]`` to functions returning types marked [[nodiscard]].
166 NoDiscardStruct f50() const;
167};
168
169// Do not add ``[[nodiscard]]`` to Lambda.
170const auto nonConstReferenceType = [] {
171 return true;
172};
173
174auto lambda1 = [](int a, int b) { return a < b; };
175auto lambda1a = [](int a) { return a; };
176auto lambda1b = []() { return true;};
177
178auto get_functor = [](bool check) {
179 return [&](const std::string& sr)->std::string {
180 if(check){
181 return std::string();
182 }
183 return std::string();
184 };
185};
186
187// Do not add ``[[nodiscard]]`` to function definition.
188bool Foo::f19() const {
189 return true;
190}
191
192template <class T>
193class Bar {
194public:
195 using value_type = T;
196 using reference = value_type &;
197 using const_reference = const value_type &;
198
199 // Do not add ``[[nodiscard]]`` to non explicit conversion functions.
200 operator bool() const { return true; }
201
202 bool empty() const;
203 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'empty' should be marked NO_DISCARD [modernize-use-nodiscard]
204 // CHECK-FIXES: NO_DISCARD bool empty() const;
205
206 // we cannot assume that the template parameter isn't a pointer
207 bool f25(value_type) const;
208
209 bool f27(reference) const;
210
211 typename T::value_type f35() const;
212
213 T f34() const;
214
215 bool f31(T) const;
216
217 bool f33(T &) const;
218
219 bool f26(const_reference) const;
220
221 bool f32(const T &) const;
222};
223
224template <typename _Tp, int cn>
225class Vec {
226public:
227 Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
228
229 Vec cross(const Vec &v) const;
230
231 template <typename T2>
232 operator Vec<T2, cn>() const;
233};
234
235template <class T>
236class Bar2 {
237public:
238 typedef T value_type;
239 typedef value_type &reference;
240 typedef const value_type &const_reference;
241
242 // we cannot assume that the template parameter isn't a pointer
243 bool f40(value_type) const;
244
245 bool f41(reference) const;
246
247 value_type f42() const;
248
249 typename T::value_type f43() const;
250
251 bool f44(const_reference) const;
252};
253
254template <class T>
255bool Bar<T>::empty() const {
256 return true;
257}
258
259// don't mark typical ``[[nodiscard]]`` candidates if the class
260// has mutable member variables
261class MutableExample {
262 mutable bool m_isempty;
263
264public:
265 bool empty() const;
266};
267

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/use-nodiscard.cpp