1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03
10
11 // Test that entities declared [[nodiscard]] as an extension by libc++, are
12 // actually declared as such when _LIBCPP_DISABLE_NODISCARD_EXT is not specified.
13
14 // All entities to which libc++ applies [[nodiscard]] as an extension should
15 // be tested here and in nodiscard_extensions.pass.cpp. They should also
16 // be listed in `UsingLibcxx.rst` in the documentation for the extension.
17
18 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
19
20 #include <algorithm>
21 #include <bit> // bit_cast
22 #include <cstddef> // to_integer
23 #include <functional> // identity
24 #include <iterator>
25 #include <memory>
26 #include <utility> // to_underlying
27
28 #include "test_macros.h"
29
30 struct P {
operator ()P31 bool operator()(int) const { return false; }
32 };
33
test_algorithms()34 void test_algorithms() {
35 int arr[1] = { 1 };
36
37 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
38 std::adjacent_find(std::begin(arr), std::end(arr));
39
40 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
41 std::adjacent_find(std::begin(arr), std::end(arr), std::greater<int>());
42
43 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
44 std::all_of(std::begin(arr), std::end(arr), P());
45
46 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
47 std::any_of(std::begin(arr), std::end(arr), P());
48
49 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
50 std::binary_search(std::begin(arr), std::end(arr), 1);
51
52 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
53 std::binary_search(std::begin(arr), std::end(arr), 1, std::greater<int>());
54
55 #if TEST_STD_VER >= 17
56 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
57 std::clamp(2, 1, 3);
58
59 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
60 std::clamp(2, 1, 3, std::greater<int>());
61 #endif
62
63 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
64 std::count_if(std::begin(arr), std::end(arr), P());
65
66 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
67 std::count(std::begin(arr), std::end(arr), 1);
68
69 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
70 std::equal_range(std::begin(arr), std::end(arr), 1);
71
72 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
73 std::equal_range(std::begin(arr), std::end(arr), 1, std::greater<int>());
74
75 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
76 std::equal(std::begin(arr), std::end(arr), std::begin(arr));
77
78 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
79 std::equal(std::begin(arr), std::end(arr), std::begin(arr),
80 std::greater<int>());
81
82 #if TEST_STD_VER >= 14
83 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
84 std::equal(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
85
86 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
87 std::equal(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
88 std::greater<int>());
89 #endif
90
91 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
92 std::find_end(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
93
94 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
95 std::find_end(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
96 std::greater<int>());
97
98 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
99 std::find_first_of(std::begin(arr), std::end(arr), std::begin(arr),
100 std::end(arr));
101
102 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
103 std::find_first_of(std::begin(arr), std::end(arr), std::begin(arr),
104 std::end(arr), std::greater<int>());
105
106 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
107 std::find_if_not(std::begin(arr), std::end(arr), P());
108
109 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
110 std::find_if(std::begin(arr), std::end(arr), P());
111
112 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
113 std::find(std::begin(arr), std::end(arr), 1);
114
115 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
116 std::get_temporary_buffer<int>(1);
117
118 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
119 std::includes(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
120
121 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
122 std::includes(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
123 std::greater<int>());
124
125 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
126 std::is_heap_until(std::begin(arr), std::end(arr));
127
128 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
129 std::is_heap_until(std::begin(arr), std::end(arr), std::greater<int>());
130
131 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
132 std::is_heap(std::begin(arr), std::end(arr));
133
134 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
135 std::is_heap(std::begin(arr), std::end(arr), std::greater<int>());
136
137 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
138 std::is_partitioned(std::begin(arr), std::end(arr), P());
139
140 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
141 std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr));
142
143 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
144 std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
145 std::greater<int>());
146
147 #if TEST_STD_VER >= 14
148 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
149 std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
150 std::end(arr));
151
152 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
153 std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
154 std::end(arr), std::greater<int>());
155 #endif
156
157 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
158 std::is_sorted_until(std::begin(arr), std::end(arr));
159
160 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
161 std::is_sorted_until(std::begin(arr), std::end(arr), std::greater<int>());
162
163 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
164 std::is_sorted(std::begin(arr), std::end(arr));
165
166 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
167 std::is_sorted(std::begin(arr), std::end(arr), std::greater<int>());
168
169 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
170 std::lexicographical_compare(std::begin(arr), std::end(arr), std::begin(arr),
171 std::end(arr));
172
173 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
174 std::lexicographical_compare(std::begin(arr), std::end(arr), std::begin(arr),
175 std::end(arr), std::greater<int>());
176
177 #if TEST_STD_VER >= 20
178 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
179 std::lexicographical_compare_three_way(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
180
181 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
182 std::lexicographical_compare_three_way(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr), std::compare_three_way());
183 #endif
184
185 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
186 std::lower_bound(std::begin(arr), std::end(arr), 1);
187
188 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
189 std::lower_bound(std::begin(arr), std::end(arr), 1, std::greater<int>());
190
191 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
192 std::max_element(std::begin(arr), std::end(arr));
193
194 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
195 std::max_element(std::begin(arr), std::end(arr), std::greater<int>());
196
197 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
198 std::max(1, 2);
199
200 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
201 std::max(1, 2, std::greater<int>());
202
203 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
204 std::max({1, 2, 3});
205
206 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
207 std::max({1, 2, 3}, std::greater<int>());
208
209 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
210 std::min_element(std::begin(arr), std::end(arr));
211
212 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
213 std::min_element(std::begin(arr), std::end(arr), std::greater<int>());
214
215 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
216 std::min(1, 2);
217
218 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
219 std::min(1, 2, std::greater<int>());
220
221 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
222 std::min({1, 2, 3});
223
224 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
225 std::min({1, 2, 3}, std::greater<int>());
226
227 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
228 std::minmax_element(std::begin(arr), std::end(arr));
229
230 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
231 std::minmax_element(std::begin(arr), std::end(arr), std::greater<int>());
232
233 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
234 std::minmax(1, 2);
235
236 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
237 std::minmax(1, 2, std::greater<int>());
238
239 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
240 std::minmax({1, 2, 3});
241
242 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
243 std::minmax({1, 2, 3}, std::greater<int>());
244
245 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
246 std::mismatch(std::begin(arr), std::end(arr), std::begin(arr));
247
248 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
249 std::mismatch(std::begin(arr), std::end(arr), std::begin(arr),
250 std::greater<int>());
251
252 #if TEST_STD_VER >= 14
253 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
254 std::mismatch(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
255
256 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
257 std::mismatch(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
258 std::greater<int>());
259 #endif
260
261 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
262 std::none_of(std::begin(arr), std::end(arr), P());
263
264 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
265 std::remove_if(std::begin(arr), std::end(arr), P());
266
267 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
268 std::remove(std::begin(arr), std::end(arr), 1);
269
270 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
271 std::search_n(std::begin(arr), std::end(arr), 1, 1);
272
273 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
274 std::search_n(std::begin(arr), std::end(arr), 1, 1, std::greater<int>());
275
276 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
277 std::search(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
278
279 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
280 std::search(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
281 std::greater<int>());
282
283 #if TEST_STD_VER >= 17
284 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
285 std::search(std::begin(arr), std::end(arr),
286 std::default_searcher(std::begin(arr), std::end(arr)));
287 #endif
288
289 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
290 std::unique(std::begin(arr), std::end(arr));
291
292 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
293 std::unique(std::begin(arr), std::end(arr), std::greater<int>());
294
295 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
296 std::upper_bound(std::begin(arr), std::end(arr), 1);
297
298 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
299 std::upper_bound(std::begin(arr), std::end(arr), 1, std::greater<int>());
300 }
301
302 template<class LV, class RV>
test_template_cast_wrappers(LV && lv,RV && rv)303 void test_template_cast_wrappers(LV&& lv, RV&& rv) {
304 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
305 std::forward<LV>(lv);
306 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
307 std::forward<RV>(rv);
308 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
309 std::move(lv);
310 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
311 std::move(rv);
312 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
313 std::move_if_noexcept(lv);
314 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
315 std::move_if_noexcept(rv);
316
317 #if TEST_STD_VER >= 17
318 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
319 std::as_const(lv);
320 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
321 std::as_const(rv);
322 #endif
323
324 #if TEST_STD_VER >= 20
325 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
326 std::identity()(lv);
327 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
328 std::identity()(rv);
329 #endif
330 }
331
test_nontemplate_cast_wrappers()332 void test_nontemplate_cast_wrappers()
333 {
334 #if TEST_STD_VER > 14
335 std::byte b{42};
336 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
337 std::to_integer<int>(b);
338 #endif
339
340 #if TEST_STD_VER > 20
341 enum E { Apple, Orange } e = Apple;
342 // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
343 std::to_underlying(e);
344 #endif
345 }
346
f()347 void f() {
348 test_algorithms();
349
350 int i = 42;
351 test_template_cast_wrappers(i, std::move(i));
352 test_nontemplate_cast_wrappers();
353 }
354