-
Notifications
You must be signed in to change notification settings - Fork 14.2k
[libc++][any] LWG3305: any_cast<void>
#78215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][any] LWG3305: any_cast<void>
#78215
Conversation
c11560a
to
595fd22
Compare
595fd22
to
328c558
Compare
@llvm/pr-subscribers-libcxx Author: Hristo Hristov (H-G-Hristov) ChangesImplements: https://wg21.link/LWG3305 Full diff: https://github.com/llvm/llvm-project/pull/78215.diff 3 Files Affected:
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index fe0f13f6e8cb2c2..29f25b63ccb863f 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -19,7 +19,7 @@
"","","","","",""
"`2392 <https://wg21.link/LWG2392>`__","""character type"" is used but not defined","Kona November 2023","","",""
"`3203 <https://wg21.link/LWG3203>`__","``span`` element access invalidation","Kona November 2023","","",""
-"`3305 <https://wg21.link/LWG3305>`__","``any_cast<void>``","Kona November 2023","","",""
+"`3305 <https://wg21.link/LWG3305>`__","``any_cast<void>``","Kona November 2023","|Complete|","18.0",""
"`3431 <https://wg21.link/LWG3431>`__","``<=>`` for containers should require ``three_way_comparable<T>`` instead of ``<=>``","Kona November 2023","","",""
"`3749 <https://wg21.link/LWG3749>`__","``common_iterator`` should handle integer-class difference types","Kona November 2023","","",""
"`3809 <https://wg21.link/LWG3809>`__","Is ``std::subtract_with_carry_engine<uint16_t>`` supposed to work","Kona November 2023","","",""
diff --git a/libcxx/include/any b/libcxx/include/any
index b9e0a8d94550ccd..a157d763c63121c 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,9 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType
template <class _ValueType>
inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
+# if _LIBCPP_STD_VER >= 26
+ static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
+# endif
static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
return std::any_cast<_ValueType>(const_cast<any*>(__any));
}
@@ -572,6 +576,9 @@ inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction
template <class _ValueType>
_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
using __any_imp::_Action;
+# if _LIBCPP_STD_VER >= 26
+ static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
+# endif
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 000000000000000..c0733e544dcb24c
--- /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, c++17, c++20, c++23
+
+// <any>
+
+// template<class T>
+// const T* any_cast(const any* operand) noexcept;
+
+// template<class T>
+// T* any_cast(any* operand) noexcept;
+
+#include <any>
+
+void test() {
+ {
+ const std::any ca = 1;
+
+ // expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}}
+ std::any_cast<void>(&ca); // expected-note {{requested here}}
+ }
+ {
+ std::any a = 1;
+
+ // expected-error-re@any:* {{static assertion failed{{.*}}_ValueType may not be void.}}
+ std::any_cast<void>(&a); // expected-note {{requested here}}
+ }
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you implemented this code only for C++26. In general we retroactively apply LWG issues to all previous standard versions. Is there a reason why you only applied this to C++26?
I am not familiar with this process. I'm happy to do what's needed to be done. So I assume I need to remove the version guards and test against the original implementation? |
Yes that is the general rule for LWG-issues. The other implementations handle them in the same fashion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@@ -555,6 +556,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType | |||
|
|||
template <class _ValueType> | |||
inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT { | |||
static_assert(!is_void_v<_ValueType>, "_ValueType may not be void."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I dislike static assert message that are same as the test. In C++17 the message is optional. However since the existing code already has these messages I'm fine to keep them.
…re secure (llvm#78215) Actions triggered by pull_request_target events have access to all repository secrets, so it is unsafe to use them when executing untrusted code. The pr-code-format workflow does not execute any untrusted code, but it passes untrused input into clang-format. An attacker could use this to exploit a flaw in clang-format and potentially gain access to the repository secrets. By splitting the workflow, we can use the pull_request target which is more secure and isolate the issue write permissions in a separate job. The pull_request target also makes it easier to test changes to the code-format-helepr.py script, because the version of the script from the pull request will be used rather than the version of the script from main. Fixes llvm#77142
…re secure (llvm#78215) Actions triggered by pull_request_target events have access to all repository secrets, so it is unsafe to use them when executing untrusted code. The pr-code-format workflow does not execute any untrusted code, but it passes untrused input into clang-format. An attacker could use this to exploit a flaw in clang-format and potentially gain access to the repository secrets. By splitting the workflow, we can use the pull_request target which is more secure and isolate the issue write permissions in a separate job. The pull_request target also makes it easier to test changes to the code-format-helepr.py script, because the version of the script from the pull request will be used rather than the version of the script from main. Fixes llvm#77142
…re secure (#78215) (#80495) Actions triggered by pull_request_target events have access to all repository secrets, so it is unsafe to use them when executing untrusted code. The pr-code-format workflow does not execute any untrusted code, but it passes untrused input into clang-format. An attacker could use this to exploit a flaw in clang-format and potentially gain access to the repository secrets. By splitting the workflow, we can use the pull_request target which is more secure and isolate the issue write permissions in a separate job. The pull_request target also makes it easier to test changes to the code-format-helepr.py script, because the version of the script from the pull request will be used rather than the version of the script from main. Fixes #77142
…re secure (llvm#78215) (llvm#80495) Actions triggered by pull_request_target events have access to all repository secrets, so it is unsafe to use them when executing untrusted code. The pr-code-format workflow does not execute any untrusted code, but it passes untrused input into clang-format. An attacker could use this to exploit a flaw in clang-format and potentially gain access to the repository secrets. By splitting the workflow, we can use the pull_request target which is more secure and isolate the issue write permissions in a separate job. The pull_request target also makes it easier to test changes to the code-format-helepr.py script, because the version of the script from the pull request will be used rather than the version of the script from main. Fixes llvm#77142
Implements: https://wg21.link/LWG3305