diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index e03b7c783bc3..b69b09483254 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -19,7 +19,7 @@ "","","","","","" "`2392 `__","""character type"" is used but not defined","Kona November 2023","","","" "`3203 `__","``span`` element access invalidation","Kona November 2023","","","" -"`3305 `__","``any_cast``","Kona November 2023","","","" +"`3305 `__","``any_cast``","Kona November 2023","|Complete|","18.0","" "`3431 `__","``<=>`` for containers should require ``three_way_comparable`` instead of ``<=>``","Kona November 2023","","","" "`3749 `__","``common_iterator`` should handle integer-class difference types","Kona November 2023","","","" "`3809 `__","Is ``std::subtract_with_carry_engine`` supposed to work","Kona November 2023","","","" diff --git a/libcxx/include/any b/libcxx/include/any index b9e0a8d94550..378dfb6e21b5 100644 --- a/libcxx/include/any +++ b/libcxx/include/any @@ -98,6 +98,7 @@ namespace std { #include <__type_traits/is_nothrow_move_constructible.h> #include <__type_traits/is_reference.h> #include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> #include <__type_traits/remove_cv.h> #include <__type_traits/remove_cvref.h> #include <__type_traits/remove_reference.h> @@ -555,6 +556,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType template inline _LIBCPP_HIDE_FROM_ABI add_pointer_t> any_cast(any const* __any) _NOEXCEPT { + static_assert(!is_void_v<_ValueType>, "_ValueType may not be void."); static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference."); return std::any_cast<_ValueType>(const_cast(__any)); } @@ -572,6 +574,7 @@ inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction template _LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT { using __any_imp::_Action; + static_assert(!is_void_v<_ValueType>, "_ValueType may not be void."); static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference."); typedef add_pointer_t<_ValueType> _ReturnType; if (__any && __any->__h_) { diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp new file mode 100644 index 000000000000..9530d63e07b0 --- /dev/null +++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++11, c++14 + +// + +// template +// const T* any_cast(const any* operand) noexcept; + +// template +// T* any_cast(any* operand) noexcept; + +#include + +void test() { + { + const std::any ca = 1; + + // expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}} + std::any_cast(&ca); // expected-note {{requested here}} + } + { + std::any a = 1; + + // expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}} + std::any_cast(&a); // expected-note {{requested here}} + } +}