blob: 54b396a5519b7daf302b08f3b3afe05727c3c2b5 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03
// Test that entities declared [[nodiscard]] as an extension by libc++, are
// only actually declared such when _LIBCPP_ENABLE_NODISCARD is specified.
// All entities to which libc++ applies [[nodiscard]] as an extension should
// be tested here and in nodiscard_extensions.pass.cpp. They should also
// be listed in `UsingLibcxx.rst` in the documentation for the extension.
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_NODISCARD
#include <algorithm>
#include <bit> // bit_cast
#include <cstddef> // to_integer
#include <functional> // identity
#include <iterator>
#include <memory>
#include <utility> // to_underlying
#include "test_macros.h"
struct P {
bool operator()(int) const { return false; }
};
void test_algorithms() {
int arr[1] = { 1 };
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::adjacent_find(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::adjacent_find(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::all_of(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::any_of(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::binary_search(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::binary_search(std::begin(arr), std::end(arr), 1, std::greater<int>());
#if TEST_STD_VER >= 17
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::clamp(2, 1, 3);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::clamp(2, 1, 3, std::greater<int>());
#endif
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::count_if(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::count(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::equal_range(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::equal_range(std::begin(arr), std::end(arr), 1, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::equal(std::begin(arr), std::end(arr), std::begin(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::equal(std::begin(arr), std::end(arr), std::begin(arr),
std::greater<int>());
#if TEST_STD_VER >= 14
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::equal(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::equal(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
std::greater<int>());
#endif
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find_end(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find_end(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find_first_of(std::begin(arr), std::end(arr), std::begin(arr),
std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find_first_of(std::begin(arr), std::end(arr), std::begin(arr),
std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find_if_not(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find_if(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::find(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::get_temporary_buffer<int>(1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::includes(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::includes(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_heap_until(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_heap_until(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_heap(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_heap(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_partitioned(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
std::greater<int>());
#if TEST_STD_VER >= 14
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
std::end(arr), std::greater<int>());
#endif
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_sorted_until(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_sorted_until(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_sorted(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::is_sorted(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::lexicographical_compare(std::begin(arr), std::end(arr), std::begin(arr),
std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::lexicographical_compare(std::begin(arr), std::end(arr), std::begin(arr),
std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::lower_bound(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::lower_bound(std::begin(arr), std::end(arr), 1, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::max_element(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::max_element(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::max(1, 2);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::max(1, 2, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::max({1, 2, 3});
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::max({1, 2, 3}, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::min_element(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::min_element(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::min(1, 2);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::min(1, 2, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::min({1, 2, 3});
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::min({1, 2, 3}, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::minmax_element(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::minmax_element(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::minmax(1, 2);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::minmax(1, 2, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::minmax({1, 2, 3});
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::minmax({1, 2, 3}, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::mismatch(std::begin(arr), std::end(arr), std::begin(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::mismatch(std::begin(arr), std::end(arr), std::begin(arr),
std::greater<int>());
#if TEST_STD_VER >= 14
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::mismatch(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::mismatch(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
std::greater<int>());
#endif
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::none_of(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::remove_if(std::begin(arr), std::end(arr), P());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::remove(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::search_n(std::begin(arr), std::end(arr), 1, 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::search_n(std::begin(arr), std::end(arr), 1, 1, std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::search(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::search(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
std::greater<int>());
#if TEST_STD_VER >= 17
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::search(std::begin(arr), std::end(arr),
std::default_searcher(std::begin(arr), std::end(arr)));
#endif
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::unique(std::begin(arr), std::end(arr));
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::unique(std::begin(arr), std::end(arr), std::greater<int>());
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::upper_bound(std::begin(arr), std::end(arr), 1);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::upper_bound(std::begin(arr), std::end(arr), 1, std::greater<int>());
}
template<class LV, class RV>
void test_template_cast_wrappers(LV&& lv, RV&& rv) {
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::forward<LV>(lv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::forward<RV>(rv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::move(lv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::move(rv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::move_if_noexcept(lv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::move_if_noexcept(rv);
#if TEST_STD_VER >= 17
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::as_const(lv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::as_const(rv);
#endif
#if TEST_STD_VER >= 20
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::identity()(lv);
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::identity()(rv);
#endif
}
void test_nontemplate_cast_wrappers()
{
#if TEST_STD_VER > 14
std::byte b{42};
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::to_integer<int>(b);
#endif
#if TEST_STD_VER > 17
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::bit_cast<unsigned int>(42);
#endif
#if TEST_STD_VER > 20
enum E { Apple, Orange } e = Apple;
// expected-warning-re@+1 {{ignoring return value of function declared with {{'nodiscard'|warn_unused_result}} attribute}}
std::to_underlying(e);
#endif
}
int main(int, char**) {
test_algorithms();
int i = 42;
test_template_cast_wrappers(i, std::move(i));
test_nontemplate_cast_wrappers();
return 0;
}