Index: libcxx/include/__utility/declval.h =================================================================== --- libcxx/include/__utility/declval.h +++ libcxx/include/__utility/declval.h @@ -27,7 +27,9 @@ _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), "Calling declval is ill-formed, see [declval]/2."); +} _LIBCPP_END_NAMESPACE_STD Index: libcxx/test/std/input.output/iostream.format/output.streams/ostream/deleted_output_functions.verify.cpp =================================================================== --- libcxx/test/std/input.output/iostream.format/output.streams/ostream/deleted_output_functions.verify.cpp +++ 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 '<<'}} } Index: libcxx/test/std/utilities/utility/declval/declval.verify.cpp =================================================================== --- /dev/null +++ libcxx/test/std/utilities/utility/declval/declval.verify.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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 main() { + if (false) { + int i = std::declval(); // expected-warning@*:* {{code will never be executed}} + (void)i; + } + + return 0; +} +// expected-error-re@*:* {{{{(static_assert|static assertion)}} failed{{.*}}Calling declval is ill-formed, see [declval]/2.}}