• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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