diff --git a/stl/inc/concepts b/stl/inc/concepts index 110177a48a..550d944040 100644 --- a/stl/inc/concepts +++ b/stl/inc/concepts @@ -40,7 +40,11 @@ concept derived_from = __is_base_of(_Base, _Derived) && __is_convertible_to(const volatile _Derived*, const volatile _Base*); template +#if !defined(__EDG__) && !defined(__clang__) // TRANSITION, DevCom-1627396 +concept convertible_to = is_convertible_v<_From, _To> +#else // ^^^ workaround / no workaround vvv concept convertible_to = __is_convertible_to(_From, _To) +#endif // ^^^ no workaround ^^^ && requires { static_cast<_To>(_STD declval<_From>()); }; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 2aa95b03e4..79c30c763f 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -331,6 +331,32 @@ struct is_convertible : bool_constant<__is_convertible_to(_From, _To)> { template _INLINE_VAR constexpr bool is_convertible_v = __is_convertible_to(_From, _To); +#if !defined(__EDG__) && !defined(__clang__) // TRANSITION, DevCom-1627396 +template +struct is_convertible<_Ty&, volatile _Ty&> : true_type {}; + +template +struct is_convertible : true_type {}; + +template +struct is_convertible<_Ty&, const volatile _Ty&> : true_type {}; + +template +struct is_convertible : true_type {}; + +template +_INLINE_VAR constexpr bool is_convertible_v<_Ty&, volatile _Ty&> = true; + +template +_INLINE_VAR constexpr bool is_convertible_v = true; + +template +_INLINE_VAR constexpr bool is_convertible_v<_Ty&, const volatile _Ty&> = true; + +template +_INLINE_VAR constexpr bool is_convertible_v = true; +#endif // ^^^ workaround + template struct is_enum : bool_constant<__is_enum(_Ty)> {}; // determine whether _Ty is an enumerated type @@ -1179,10 +1205,6 @@ struct basic_common_reference {}; template _Ty _Returns_exactly() noexcept; // not defined -template -using _Cond_res = // N4810 [meta.trans.other]/2.4 - decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>()); - template struct _Copy_cv_impl { template @@ -1223,6 +1245,34 @@ struct _Add_qualifiers<_Ty1&&> { using _Apply = add_rvalue_reference_t<_Copy_cv<_Ty1, _Ty2>>; }; +#if !defined(__EDG__) && !defined(__clang__) // TRANSITION, DevCom-876860 +template +using _Cond_res_if_right = // N4810 [meta.trans.other]/2.4 + decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>()); + +template +using _Is_scalar_or_array = disjunction, is_array<_Ty>>; + +template +struct _Cond_res_workaround {}; + +template +struct _Cond_res_workaround<_Ty1, _Ty2, void_t<_Cond_res_if_right<_Ty1, _Ty2>>> { + using _Uty = remove_cvref_t<_Ty1>; + using type = conditional_t>, _Is_scalar_or_array<_Uty>, + disjunction, is_rvalue_reference<_Ty2>>, + conjunction, is_lvalue_reference<_Ty2>>>>, + decay_t<_Copy_cv, remove_reference_t<_Ty2>>>, _Cond_res_if_right<_Ty1, _Ty2>>; +}; + +template +using _Cond_res = typename _Cond_res_workaround<_Ty1, _Ty2>::type; +#else // ^^^ workaround / no workaround vvv +template +using _Cond_res = // N4810 [meta.trans.other]/2.4 + decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>()); +#endif // ^^^ no workaround ^^^ + template struct common_reference; diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 5693cb5e76..d09076833f 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -262,17 +262,6 @@ std/atomics/atomics.types.generic/copy_semantics_traits.pass.cpp FAIL # DevCom-409222 "Constructing rvalue reference from non-reference-related lvalue reference" std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp:0 FAIL -# DevCom-876860 "conditional operator errors" blocks readable. -std/concepts/concepts.lang/concept.common/common_with.compile.pass.cpp:0 FAIL -std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp:0 FAIL -std/containers/views/span.cons/iterator_sentinel.pass.cpp:0 FAIL -std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/bidirectional_iterator.compile.pass.cpp:0 FAIL -std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp:0 FAIL -std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/indirectly_readable.compile.pass.cpp:0 FAIL -std/iterators/iterator.requirements/iterator.concepts/iterator.concept.forward/forward_iterator.compile.pass.cpp:0 FAIL -std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp:0 FAIL -std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp:0 FAIL - # VSO-1271673 "static analyzer doesn't know about short-circuiting" std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp:0 FAIL std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp:0 FAIL @@ -290,9 +279,6 @@ std/utilities/utility/pairs/pairs.spec/three_way_comparison.pass.cpp:0 FAIL # DevCom-1626727: bogus "failure was caused by a conversion from void* to a pointer-to-object type" for conversion to void std/algorithms/robust_re_difference_type.compile.pass.cpp:0 FAIL -# DevCom-1627396: C1XX's __is_convertible_to intrinsic mis-handles volatile array lvalues -std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp:0 FAIL - # DevCom-1628714: C1XX refuses nullptr_t == reference-to-function in a requires expression std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp:0 FAIL diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 3179d7c8cf..d8e13f3309 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -262,17 +262,6 @@ atomics\atomics.types.generic\copy_semantics_traits.pass.cpp # DevCom-409222 "Constructing rvalue reference from non-reference-related lvalue reference" utilities\meta\meta.unary\meta.unary.prop\is_constructible.pass.cpp -# DevCom-876860 "conditional operator errors" blocks readable. -concepts\concepts.lang\concept.common\common_with.compile.pass.cpp -concepts\concepts.lang\concept.commonref\common_reference.compile.pass.cpp -containers\views\span.cons\iterator_sentinel.pass.cpp -iterators\iterator.requirements\iterator.concepts\iterator.concept.bidir\bidirectional_iterator.compile.pass.cpp -iterators\iterator.requirements\iterator.concepts\iterator.concept.random.access\contiguous_iterator.compile.pass.cpp -iterators\iterator.requirements\iterator.concepts\iterator.concept.readable\indirectly_readable.compile.pass.cpp -iterators\iterator.requirements\iterator.concepts\iterator.concept.forward\forward_iterator.compile.pass.cpp -iterators\iterator.requirements\iterator.concepts\iterator.concept.input\input_iterator.compile.pass.cpp -iterators\iterator.requirements\iterator.concepts\iterator.concept.random.access\random_access_iterator.compile.pass.cpp - # VSO-1271673 "static analyzer doesn't know about short-circuiting" algorithms\alg.sorting\alg.sort\partial.sort\partial_sort.pass.cpp algorithms\alg.sorting\alg.sort\partial.sort\partial_sort_comp.pass.cpp @@ -290,9 +279,6 @@ utilities\utility\pairs\pairs.spec\three_way_comparison.pass.cpp # DevCom-1626727: bogus "failure was caused by a conversion from void* to a pointer-to-object type" for conversion to void algorithms\robust_re_difference_type.compile.pass.cpp -# DevCom-1627396: C1XX's __is_convertible_to intrinsic mis-handles volatile array lvalues -concepts\concepts.lang\concept.swappable\swappable_with.compile.pass.cpp - # DevCom-1628714: C1XX refuses nullptr_t == reference-to-function in a requires expression concepts\concepts.compare\concept.equalitycomparable\equality_comparable_with.compile.pass.cpp diff --git a/tests/std/test.lst b/tests/std/test.lst index 8379ab0380..34746ba185 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -192,6 +192,7 @@ tests\GH_002039_byte_is_not_trivially_swappable tests\GH_002058_debug_iterator_race tests\GH_002120_streambuf_seekpos_and_seekoff tests\GH_002488_promise_not_default_constructible_types +tests\GH_002581_common_reference_workaround tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function tests\LWG3146_excessive_unwrapping_ref_cref diff --git a/tests/std/tests/GH_002581_common_reference_workaround/env.lst b/tests/std/tests/GH_002581_common_reference_workaround/env.lst new file mode 100644 index 0000000000..7b6bcff483 --- /dev/null +++ b/tests/std/tests/GH_002581_common_reference_workaround/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\strict_concepts_20_matrix.lst diff --git a/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp b/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp new file mode 100644 index 0000000000..1fe3ffe140 --- /dev/null +++ b/tests/std/tests/GH_002581_common_reference_workaround/test.compile.pass.cpp @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +using namespace std; + +struct Test {}; +enum Unscoped {}; +enum class Scoped {}; + +// Tests for raw pointers +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); +static_assert(contiguous_iterator); + +// Tests for move_iterator specializations +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); +static_assert(input_iterator>); + +int main() {} // COMPILE-ONLY