diff --git a/libcxx/include/__utility/declval.h b/libcxx/include/__utility/declval.h --- a/libcxx/include/__utility/declval.h +++ b/libcxx/include/__utility/declval.h @@ -27,7 +27,11 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP template -decltype(std::__declval<_Tp>(0)) declval() _NOEXCEPT; +_LIBCPP_HIDE_FROM_ABI decltype(std::__declval<_Tp>(0)) declval() _NOEXCEPT { + static_assert(!__is_same(_Tp, _Tp), + "std::declval can only be used in an unevaluated context. " + "It's likely that your current usage is trying to extract a value from the function."); +} _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream/deleted_output_functions.verify.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream/deleted_output_functions.verify.cpp --- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream/deleted_output_functions.verify.cpp +++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream/deleted_output_functions.verify.cpp @@ -18,38 +18,47 @@ void f() { std::ostringstream s; +#ifndef TEST_HAS_NO_CHAR8_T + char8_t c8_s[] = u8"test"; + const char8_t* c8_cs = u8"test"; +#endif + char16_t c16_s[] = u"test"; + const char16_t* c16_cs = u"test"; + char32_t c32_s[] = U"test"; + const char32_t* c32_cs = U"test"; #ifndef TEST_HAS_NO_WIDE_CHARACTERS - - s << wchar_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} + wchar_t w_s[] = L"test"; + const wchar_t* w_cs = L"test"; + s << wchar_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + s << w_s; // expected-error {{overload resolution selected deleted operator '<<'}} + s << w_cs; // expected-error {{overload resolution selected deleted operator '<<'}} std::wostringstream sw; # ifndef TEST_HAS_NO_CHAR8_T - sw << char8_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} + sw << char8_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + sw << c8_s; // expected-error {{overload resolution selected deleted operator '<<'}} + sw << c8_cs; // expected-error {{overload resolution selected deleted operator '<<'}} # endif - sw << char16_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << char32_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - sw << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} + sw << char16_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + sw << c16_s; // expected-error {{overload resolution selected deleted operator '<<'}} + sw << c16_cs; // expected-error {{overload resolution selected deleted operator '<<'}} + sw << char32_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + sw << c32_s; // expected-error {{overload resolution selected deleted operator '<<'}} + sw << c32_cs; // expected-error {{overload resolution selected deleted operator '<<'}} #endif // TEST_HAS_NO_WIDE_CHARACTERS #ifndef TEST_HAS_NO_CHAR8_T - s << char8_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} + s << char8_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + s << c8_s; // expected-error {{overload resolution selected deleted operator '<<'}} + s << c8_cs; // expected-error {{overload resolution selected deleted operator '<<'}} #endif - s << char16_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << char32_t(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} - s << std::declval(); // expected-error {{overload resolution selected deleted operator '<<'}} + s << char16_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + s << c16_s; // expected-error {{overload resolution selected deleted operator '<<'}} + s << c16_cs; // expected-error {{overload resolution selected deleted operator '<<'}} + s << char32_t(); // expected-error {{overload resolution selected deleted operator '<<'}} + s << c32_s; // expected-error {{overload resolution selected deleted operator '<<'}} + s << c32_cs; // expected-error {{overload resolution selected deleted operator '<<'}} } diff --git a/libcxx/test/std/utilities/utility/declval/declval.verify.cpp b/libcxx/test/std/utilities/utility/declval/declval.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/declval/declval.verify.cpp @@ -0,0 +1,16 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// template typename add_rvalue_reference::type declval() noexcept; + +#include + +int x = std::declval< + int>(); // expected-error-re@*:* {{static assertion failed{{.*}}std::declval can only be used in an unevaluated context.}}