From cb120ed92d83568d790cee5849a093eda546b53f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 26 Feb 2026 14:23:44 +0800 Subject: [PATCH 1/4] Fix LLVM-176877 for MSVC STL w/ Clang --- stl/inc/any | 9 +++++---- tests/std/tests/P0220R1_any/test.cpp | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/stl/inc/any b/stl/inc/any index c9d30736a57..9560c02911e 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -130,10 +130,11 @@ public: _Move_from(_That); } - template , any>>, - negation<_Is_specialization, in_place_type_t>>, - is_copy_constructible>>, - int> = 0> + template , any> && !_Is_specialization_v, in_place_type_t>, + int> = 0, // Separate these conditions into two `enable_if_t`s to avoid meta-recursion. + // See LLVM-176877 and GH-6109. + enable_if_t>, int> = 0> any(_ValueType&& _Value) { // initialize with _Value _Emplace>(_STD forward<_ValueType>(_Value)); } diff --git a/tests/std/tests/P0220R1_any/test.cpp b/tests/std/tests/P0220R1_any/test.cpp index 391bb7b0ed1..2bf01073c69 100644 --- a/tests/std/tests/P0220R1_any/test.cpp +++ b/tests/std/tests/P0220R1_any/test.cpp @@ -1160,6 +1160,24 @@ void test_sfinae_constraints() { } } +// https://llvm.org/PR176877 +// Avoid constraint meta-recursion for a type both convertible from and to std::any. +template ::value> +void test_default_template_argument_is_copy_constructible(T) {} + +template > +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 run_test() { test_copy_move_value(); test_copy_move_value(); @@ -1167,8 +1185,9 @@ int run_test() { test_copy_value_throws(); test_move_value_throws(); test_sfinae_constraints(); + test_no_constraint_recursion(); - return 0; + return 0; } } // namespace ctor::value // -- END: test/std/utilities/any/any.class/any.cons/value.pass.cpp From a9ee19a09f9dc31501ab6f0089802d4d68d6c2a5 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 26 Feb 2026 17:25:18 +0800 Subject: [PATCH 2/4] Also mirror `#include ` ... which is quite unnecessary, though. --- tests/std/tests/P0220R1_any/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/P0220R1_any/test.cpp b/tests/std/tests/P0220R1_any/test.cpp index 2bf01073c69..c8b1f4ec43c 100644 --- a/tests/std/tests/P0220R1_any/test.cpp +++ b/tests/std/tests/P0220R1_any/test.cpp @@ -1040,6 +1040,7 @@ int run_test() #include #include +#include #include "any_helpers.h" #include "count_new.h" From 9da89154262ecb2904e635475eceb7ba58520232 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 26 Feb 2026 08:56:00 -0800 Subject: [PATCH 3/4] Cite the ordering guarantee. --- stl/inc/any | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stl/inc/any b/stl/inc/any index 9560c02911e..e9d7f0731dd 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -133,7 +133,9 @@ public: template , any> && !_Is_specialization_v, in_place_type_t>, int> = 0, // Separate these conditions into two `enable_if_t`s to avoid meta-recursion. - // See LLVM-176877 and GH-6109. + // See LLVM-176877 and GH-6109. N5032 [temp.deduct.general]/7 guarantees: + // "The substitution proceeds in lexical order and stops when + // a condition that causes deduction to fail is encountered." enable_if_t>, int> = 0> any(_ValueType&& _Value) { // initialize with _Value _Emplace>(_STD forward<_ValueType>(_Value)); From dac39bd17386e7e966b9a3f345f4785ff2dd71c4 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 27 Feb 2026 12:43:14 -0800 Subject: [PATCH 4/4] any.cons/value.pass.cpp is now passing. --- tests/libcxx/expected_results.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index f43ba600439..971a27c8889 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -1112,9 +1112,6 @@ std/input.output/file.streams/fstreams/filebuf.virtuals/xsputn.pass.cpp:1 FAIL std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp:0 FAIL std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp:1 FAIL -# Not analyzed. Clang error: no member named 'value' in 'std::is_copy_constructible' -std/utilities/any/any.class/any.cons/value.pass.cpp:2 FAIL - # Not analyzed. Assertion failed: globalMemCounter.checkOutstandingNewLessThanOrEqual(1) std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp FAIL std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp FAIL