Author: A. Jiang Date: 2026-02-06T09:20:02Z New Revision: 88b78bcec6676b24ced83d684467a34133d63659
URL: https://github.com/llvm/llvm-project/commit/88b78bcec6676b24ced83d684467a34133d63659 DIFF: https://github.com/llvm/llvm-project/commit/88b78bcec6676b24ced83d684467a34133d63659.diff LOG: [libc++] Short-cut constraints of single-argument `any` constructor (#177082) When a default template argument of a function template uses `std::is_copy_constructible<T>::value` and `T` is convertible from and to `any`, the changes in 21dc73f6a46cd786394f10f5aef46ec4a2d26175 would introduce constraint meta-recursion when compiling with Clang. This patch short-cuts constraints of the related constructor to avoid computing `is_copy_constructible<T>` when `decay_t<T>` is `any`, which gets rid of constraint meta-recursion in the overload resolution of copy construction of `T`. Fixes #176877. (cherry picked from commit aa5428864e86f8e38806fc92d14cadc68b3d0667) Added: Modified: libcxx/include/any libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp Removed: ################################################################################ diff --git a/libcxx/include/any b/libcxx/include/any index 382a7c894b86b..d9368df75296e 100644 --- a/libcxx/include/any +++ b/libcxx/include/any @@ -89,6 +89,7 @@ namespace std { # include <__type_traits/add_cv_quals.h> # include <__type_traits/add_pointer.h> # include <__type_traits/conditional.h> +# include <__type_traits/conjunction.h> # include <__type_traits/decay.h> # include <__type_traits/enable_if.h> # include <__type_traits/is_constructible.h> @@ -97,6 +98,7 @@ namespace std { # include <__type_traits/is_reference.h> # include <__type_traits/is_same.h> # include <__type_traits/is_void.h> +# include <__type_traits/negation.h> # include <__type_traits/remove_cv.h> # include <__type_traits/remove_cvref.h> # include <__type_traits/remove_reference.h> @@ -201,10 +203,11 @@ public: __other.__call(_Action::_Move, this); } - template <class _ValueType, - class _Tp = decay_t<_ValueType>, - enable_if_t<!is_same_v<_Tp, any> && !__is_inplace_type<_ValueType>::value && is_copy_constructible_v<_Tp>, - int> = 0> + template < + class _ValueType, + class _Tp = decay_t<_ValueType>, + enable_if_t<_And<_Not<is_same<_Tp, any>>, _Not<__is_inplace_type<_ValueType>>, is_copy_constructible<_Tp>>::value, + int> = 0> _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value) : __h_(nullptr) { __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__value)); } diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp index 120dfc22f3fbc..b78f72210f7da 100644 --- a/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp +++ b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp @@ -21,6 +21,7 @@ #include <any> #include <cassert> +#include <type_traits> #include "any_helpers.h" #include "count_new.h" @@ -140,6 +141,24 @@ void test_sfinae_constraints() { } } +// https://llvm.org/PR176877 +// Avoid constraint meta-recursion for a type both convertible from and to std::any. +template <class T, bool = std::is_copy_constructible<T>::value> +void test_default_template_argument_is_copy_constructible(T) {} + +template <class T, bool = std::is_copy_constructible_v<T>> +void test_default_template_argument_is_copy_constructible_v(T) {} + +void test_no_constraint_recursion() { + struct ConvertibleFromAndToAny { + ConvertibleFromAndToAny(std::any) {} + }; + + ConvertibleFromAndToAny src = std::any{}; + test_default_template_argument_is_copy_constructible(src); + test_default_template_argument_is_copy_constructible_v(src); +} + int main(int, char**) { test_copy_move_value<small>(); test_copy_move_value<large>(); @@ -147,6 +166,7 @@ int main(int, char**) { test_copy_value_throws<large_throws_on_copy>(); test_move_value_throws(); test_sfinae_constraints(); + test_no_constraint_recursion(); - return 0; + return 0; } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
