Skip to content

[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

Merged
merged 5 commits into from
Jan 20, 2024

Conversation

H-G-Hristov
Copy link
Contributor

@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/LWG3305-any_cast-void branch from c11560a to 595fd22 Compare January 16, 2024 06:11
@H-G-Hristov H-G-Hristov force-pushed the hgh/libcxx/LWG3305-any_cast-void branch from 595fd22 to 328c558 Compare January 16, 2024 06:14
@H-G-Hristov H-G-Hristov marked this pull request as ready for review January 16, 2024 07:44
@H-G-Hristov H-G-Hristov requested a review from a team as a code owner January 16, 2024 07:44
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 16, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 16, 2024

@llvm/pr-subscribers-libcxx

Author: Hristo Hristov (H-G-Hristov)

Changes

Implements: https://wg21.link/LWG3305


Full diff: https://github.com/llvm/llvm-project/pull/78215.diff

3 Files Affected:

  • (modified) libcxx/docs/Status/Cxx2cIssues.csv (+1-1)
  • (modified) libcxx/include/any (+7)
  • (added) libcxx/test/std/utilities/any/any.nonmembers/any.cast/void.verify.cpp (+34)
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}}
+  }
+}

Copy link
Member

@mordante mordante left a 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?

@mordante mordante self-assigned this Jan 16, 2024
@H-G-Hristov
Copy link
Contributor Author

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?

@mordante
Copy link
Member

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.

@H-G-Hristov H-G-Hristov requested a review from mordante January 19, 2024 07:15
Copy link
Member

@mordante mordante left a 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.");
Copy link
Member

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.

@Zingam Zingam merged commit 552f554 into llvm:main Jan 20, 2024
@H-G-Hristov H-G-Hristov deleted the hgh/libcxx/LWG3305-any_cast-void branch January 20, 2024 06:15
tstellar added a commit to tstellar/llvm-project that referenced this pull request Feb 2, 2024
…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
tstellar added a commit to tstellar/llvm-project that referenced this pull request Feb 3, 2024
…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
tstellar added a commit that referenced this pull request Mar 22, 2024
…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
chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants