From c07f5158ec06134b763e746aff6ae64d9d457969 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 14 Sep 2022 16:08:59 +0800 Subject: [PATCH 1/3] Unblock two tests and update reason for failure --- tests/libcxx/expected_results.txt | 20 ++++++++++---------- tests/libcxx/skipped_tests.txt | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index ff6212542d..da8628d976 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -385,15 +385,19 @@ std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp FAIL std/depr/depr.c.headers/math_h.pass.cpp FAIL std/numerics/c.math/cmath.pass.cpp FAIL -# GH-2358: : path's comparison operators are IF-NDR -std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp FAIL - # GH-1374: Spaceship CPO wording in [cmp.alg] needs an overhaul # (Technically an STL bug until the wording in the working draft is fixed to agree.) std/language.support/cmp/cmp.alg/partial_order.pass.cpp FAIL std/language.support/cmp/cmp.alg/strong_order.pass.cpp FAIL std/language.support/cmp/cmp.alg/weak_order.pass.cpp FAIL +# GH-1596: : unqualified calls to _Adl_verify_range incorrectly cause instantiation +std/algorithms/robust_against_adl.compile.pass.cpp FAIL +std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp FAIL + +# GH-3100: etc.: ADL should be avoided when calling _Construct_in_place and its friends +std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp FAIL + # *** CRT BUGS *** # We're permanently missing aligned_alloc(). @@ -640,6 +644,9 @@ std/ranges/range.adaptors/range.drop/ctor.default.pass.cpp FAIL std/ranges/range.adaptors/range.transform/iterator/subscript.pass.cpp FAIL std/ranges/range.utility/view.interface/view.interface.pass.cpp FAIL +# non-portable test for strengthened iterator concept +std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp FAIL + # tests invalid range std/utilities/memory/specialized.algorithms/uninitialized.copy/ranges_uninitialized_copy.pass.cpp SKIPPED std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp SKIPPED @@ -840,13 +847,6 @@ std/re/re.const/re.matchflag/match_prev_avail.pass.cpp FAIL # Not yet analyzed. Many diagnostics. std/input.output/filesystems/class.path/path.member/path.charconv.pass.cpp FAIL -# Not yet analyzed. Probably ADL shenanigans. -std/algorithms/robust_against_adl.compile.pass.cpp FAIL -std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp FAIL -std/thread/thread.threads/thread.thread.class/thread.thread.constr/robust_against_adl.pass.cpp FAIL -std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp FAIL -std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp FAIL - # Not yet analyzed. Possibly C1XX constexpr bug. std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp:0 FAIL diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 489f32a0a8..bf1d1d3419 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -385,15 +385,19 @@ utilities\meta\meta.trans\meta.trans.other\aligned_storage.pass.cpp depr\depr.c.headers\math_h.pass.cpp numerics\c.math\cmath.pass.cpp -# GH-2358: : path's comparison operators are IF-NDR -input.output\filesystems\class.path\range_concept_conformance.compile.pass.cpp - # GH-1374: Spaceship CPO wording in [cmp.alg] needs an overhaul # (Technically an STL bug until the wording in the working draft is fixed to agree.) language.support\cmp\cmp.alg\partial_order.pass.cpp language.support\cmp\cmp.alg\strong_order.pass.cpp language.support\cmp\cmp.alg\weak_order.pass.cpp +# GH-1596: : unqualified calls to _Adl_verify_range incorrectly cause instantiation +algorithms\robust_against_adl.compile.pass.cpp +strings\basic.string\string.modifiers\robust_against_adl.pass.cpp + +# GH-3100: etc.: ADL should be avoided when calling _Construct_in_place and its friends +utilities\function.objects\func.wrap\func.wrap.func\robust_against_adl.pass.cpp + # *** CRT BUGS *** # We're permanently missing aligned_alloc(). @@ -640,6 +644,9 @@ ranges\range.adaptors\range.drop\ctor.default.pass.cpp ranges\range.adaptors\range.transform\iterator\subscript.pass.cpp ranges\range.utility\view.interface\view.interface.pass.cpp +# non-portable test for strengthened iterator concept +input.output\filesystems\class.path\range_concept_conformance.compile.pass.cpp + # tests invalid range utilities\memory\specialized.algorithms\uninitialized.copy\ranges_uninitialized_copy.pass.cpp utilities\memory\specialized.algorithms\uninitialized.move\ranges_uninitialized_move.pass.cpp @@ -836,13 +843,6 @@ re\re.const\re.matchflag\match_prev_avail.pass.cpp # Not yet analyzed. Many diagnostics. input.output\filesystems\class.path\path.member\path.charconv.pass.cpp -# Not yet analyzed. Probably ADL shenanigans. -algorithms\robust_against_adl.compile.pass.cpp -strings\basic.string\string.modifiers\robust_against_adl.pass.cpp -thread\thread.threads\thread.thread.class\thread.thread.constr\robust_against_adl.pass.cpp -utilities\function.objects\func.wrap\func.wrap.func\robust_against_adl.pass.cpp -utilities\function.objects\refwrap\refwrap.invoke\robust_against_adl.pass.cpp - # Not yet analyzed. Possibly C1XX constexpr bug. utilities\function.objects\func.invoke\invoke_constexpr.pass.cpp From ccd6168a4707ffd5206a86bfa58d05b00dbbbe3f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 14 Sep 2022 16:15:14 +0800 Subject: [PATCH 2/3] Fix small ADL-related problems For `reference_wrapper` and `thread`. And update the references to the latest Working Draft as driven-by change. --- stl/inc/thread | 4 ++-- stl/inc/type_traits | 53 +++++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/stl/inc/thread b/stl/inc/thread index 0865c5cd79..94971c3407 100644 --- a/stl/inc/thread +++ b/stl/inc/thread @@ -51,7 +51,7 @@ private: static unsigned int __stdcall _Invoke(void* _RawVals) noexcept /* terminates */ { // adapt invoke of user's callable object to _beginthreadex's thread procedure const unique_ptr<_Tuple> _FnVals(static_cast<_Tuple*>(_RawVals)); - _Tuple& _Tup = *_FnVals; + _Tuple& _Tup = *(_FnVals.get()); // avoid ADL, handle incomplete types _STD invoke(_STD move(_STD get<_Indices>(_Tup))...); _Cnd_do_broadcast_at_thread_exit(); // TRANSITION, ABI return 0; @@ -311,7 +311,7 @@ public: jthread& operator=(jthread&& _Other) noexcept { // note: the standard specifically disallows making self-move-assignment a no-op here - // N4861 [thread.jthread.cons]/13 + // N4917 33.4.4.2 [thread.jthread.cons]/13 // Effects: If joinable() is true, calls request_stop() and then join(). Assigns the state // of x to *this and sets x to a default constructed state. _Try_cancel_and_join(); diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 495a4033b9..a4eb18d0b1 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -140,7 +140,7 @@ using add_rvalue_reference_t = typename _Add_reference<_Ty>::_Rvalue; template add_rvalue_reference_t<_Ty> declval() noexcept { - static_assert(_Always_false<_Ty>, "Calling declval is ill-formed, see N4892 [declval]/2."); + static_assert(_Always_false<_Ty>, "Calling declval is ill-formed, see N4917 22.2.6 [declval]/2."); } template @@ -1189,8 +1189,8 @@ using _Conditional_type = decltype(false ? _STD declval<_Ty1>() : _STD declval<_ template struct _Const_lvalue_cond_oper {}; -// N4810 [meta.trans.other]/3.3.4 (per the proposed resolution of LWG-3205): "Otherwise, if remove_cvref_t denotes -// a type..." +// N4917 21.3.8.7 [meta.trans.other]/3.3.4 (per the proposed resolution of LWG-3205): "Otherwise, if +// remove_cvref_t denotes a type..." template struct _Const_lvalue_cond_oper<_Ty1, _Ty2, void_t<_Conditional_type>> { using type = remove_cvref_t<_Conditional_type>; @@ -1267,11 +1267,11 @@ struct _Copy_cv_impl { using _Apply = const volatile _To; }; template -using _Copy_cv = // N4810 [meta.trans.other]/2.3 +using _Copy_cv = // N4917 21.3.8.7 [meta.trans.other]/2.3 typename _Copy_cv_impl<_From>::template _Apply<_To>; template -struct _Add_qualifiers { // _Add_qualifiers::template _Apply is XREF(A) from N4810 [meta.trans.other]/2.1 +struct _Add_qualifiers { // _Add_qualifiers::template _Apply is XREF(A) from N4917 21.3.8.7 [meta.trans.other]/2.1 template using _Apply = _Copy_cv<_Ty1, _Ty2>; }; @@ -1288,7 +1288,7 @@ struct _Add_qualifiers<_Ty1&&> { #if !defined(__EDG__) && !defined(__clang__) // TRANSITION, DevCom-10095944 template -using _Cond_res_if_right = // N4810 [meta.trans.other]/2.4 +using _Cond_res_if_right = // N4917 21.3.8.7 [meta.trans.other]/2.4 decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>()); template @@ -1310,7 +1310,7 @@ 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 +using _Cond_res = // N4917 21.3.8.7 [meta.trans.other]/2.4 decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>()); #endif // ^^^ no workaround ^^^ @@ -1320,30 +1320,30 @@ struct common_reference; template using common_reference_t = typename common_reference<_Types...>::type; -// N4810 [meta.trans.other]/5.1: "If sizeof...(T) is zero ..." +// N4917 21.3.8.7 [meta.trans.other]/5.1: "If sizeof...(T) is zero ..." template <> struct common_reference<> {}; -// N4810 [meta.trans.other]/5.2: "...if sizeof...(T) is one ..." +// N4917 21.3.8.7 [meta.trans.other]/5.2: "...if sizeof...(T) is one ..." template struct common_reference<_Ty> { using type = _Ty; }; -// N4810 [meta.trans.other]/5.3: "...if sizeof...(T) is two..." +// N4917 21.3.8.7 [meta.trans.other]/5.3: "...if sizeof...(T) is two..." -// N4810 [meta.trans.other]/5.3.4: "if common_type_t is well-formed..." -// N4810 [meta.trans.other]/5.3.5: "Otherwise, there shall be no member type." +// N4917 21.3.8.7 [meta.trans.other]/5.3.4: "if common_type_t is well-formed..." +// N4917 21.3.8.7 [meta.trans.other]/5.3.5: "Otherwise, there shall be no member type." template struct _Common_reference2C : common_type<_Ty1, _Ty2> {}; -// N4810 [meta.trans.other]/5.3.3: "if COND_RES(T1, T2) is well-formed..." +// N4917 21.3.8.7 [meta.trans.other]/5.3.3: "if COND_RES(T1, T2) is well-formed..." template struct _Common_reference2C<_Ty1, _Ty2, void_t<_Cond_res<_Ty1, _Ty2>>> { using type = _Cond_res<_Ty1, _Ty2>; }; -// N4810 [meta.trans.other]/5.3.2: "if basic_common_reference<[...]>::type is well-formed..." +// N4917 21.3.8.7 [meta.trans.other]/5.3.2: "if basic_common_reference<[...]>::type is well-formed..." template using _Basic_specialization = typename basic_common_reference, remove_cvref_t<_Ty2>, _Add_qualifiers<_Ty1>::template _Apply, _Add_qualifiers<_Ty2>::template _Apply>::type; @@ -1356,7 +1356,7 @@ struct _Common_reference2B<_Ty1, _Ty2, void_t<_Basic_specialization<_Ty1, _Ty2>> using type = _Basic_specialization<_Ty1, _Ty2>; }; -// N4810 [meta.trans.other]/5.3.1: "If T1 and T2 are reference types and COMMON_REF(T1, T2) is well-formed..." +// N4917 21.3.8.7 [meta.trans.other]/5.3.1: "If T1 and T2 are reference types and COMMON_REF(T1, T2) is well-formed..." template struct _Common_reference2A : _Common_reference2B<_Ty1, _Ty2> {}; @@ -1366,17 +1366,19 @@ using _LL_common_ref = _Result; template struct _Common_reference2A<_Ty1&, _Ty2&, void_t<_LL_common_ref<_Ty1, _Ty2>>> { - using type = _LL_common_ref<_Ty1, _Ty2>; // "both lvalues" case from N4810 [meta.trans.other]/2.5 + using type = _LL_common_ref<_Ty1, _Ty2>; // "both lvalues" case from N4917 21.3.8.7 [meta.trans.other]/2.5 }; template struct _Common_reference2A<_Ty1&&, _Ty2&, enable_if_t>>> { - using type = _LL_common_ref; // "rvalue and lvalue" case from N4810 [meta.trans.other]/2.7 + using type = + _LL_common_ref; // "rvalue and lvalue" case from N4917 21.3.8.7 [meta.trans.other]/2.7 }; template struct _Common_reference2A<_Ty1&, _Ty2&&, enable_if_t>>> { - using type = _LL_common_ref; // "lvalue and rvalue" case from N4810 [meta.trans.other]/2.8 + using type = + _LL_common_ref; // "lvalue and rvalue" case from N4917 21.3.8.7 [meta.trans.other]/2.8 }; template @@ -1386,13 +1388,13 @@ template struct _Common_reference2A<_Ty1&&, _Ty2&&, enable_if_t< is_convertible_v<_Ty1&&, _RR_common_ref<_Ty1, _Ty2>> && is_convertible_v<_Ty2&&, _RR_common_ref<_Ty1, _Ty2>>>> { - using type = _RR_common_ref<_Ty1, _Ty2>; // "both rvalues" case from N4810 [meta.trans.other]/2.6 + using type = _RR_common_ref<_Ty1, _Ty2>; // "both rvalues" case from N4917 21.3.8.7 [meta.trans.other]/2.6 }; template struct common_reference<_Ty1, _Ty2> : _Common_reference2A<_Ty1, _Ty2> {}; -// N4810 [meta.trans.other]/5.4: "if sizeof...(T) is greater than two..." +// N4917 21.3.8.7 [meta.trans.other]/5.4: "if sizeof...(T) is greater than two..." template struct _Fold_common_reference {}; template @@ -1448,8 +1450,9 @@ template class reference_wrapper; // std::invoke isn't constexpr in C++17, and normally implementers are forbidden from "strengthening" constexpr -// (WG21-N4842 [constexpr.functions]/1), yet both std::apply and std::visit are required to be constexpr and have -// invoke-like behavior. As a result, we've chosen to apply the part of P1065R2 resolving LWG-2894 as a defect report. +// (WG21-N4917 16.4.6.7 [constexpr.functions]/1), yet both std::apply and std::visit are required to be constexpr and +// have invoke-like behavior. As a result, we've chosen to apply the part of P1065R2 resolving LWG-2894 as a defect +// report. enum class _Invoker_strategy { _Functor, @@ -1854,7 +1857,8 @@ template struct _Refwrap_has_ctor_from : false_type {}; template -struct _Refwrap_has_ctor_from<_Ty, _Uty, void_t(_STD declval<_Uty>()))>> : true_type {}; +struct _Refwrap_has_ctor_from<_Ty, _Uty, void_t(_STD declval<_Uty>()))>> + : true_type {}; // qualified: avoid ADL, handle incomplete types template class reference_wrapper @@ -1871,7 +1875,8 @@ public: template , reference_wrapper>>, _Refwrap_has_ctor_from<_Ty, _Uty>>, int> = 0> - _CONSTEXPR20 reference_wrapper(_Uty&& _Val) noexcept(noexcept(_Refwrap_ctor_fun<_Ty>(_STD declval<_Uty>()))) { + _CONSTEXPR20 reference_wrapper(_Uty&& _Val) noexcept( + noexcept(_STD _Refwrap_ctor_fun<_Ty>(_STD declval<_Uty>()))) { // qualified: avoid ADL, handle incomplete types _Ty& _Ref = static_cast<_Uty&&>(_Val); _Ptr = _STD addressof(_Ref); } From b885e4b1e7437a2f9065e6fd1f95d695ee37074d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 22 Sep 2022 21:08:04 -0700 Subject: [PATCH 3/3] Code review feedback. --- stl/inc/thread | 4 ++-- stl/inc/type_traits | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/thread b/stl/inc/thread index 94971c3407..5008915f70 100644 --- a/stl/inc/thread +++ b/stl/inc/thread @@ -51,7 +51,7 @@ private: static unsigned int __stdcall _Invoke(void* _RawVals) noexcept /* terminates */ { // adapt invoke of user's callable object to _beginthreadex's thread procedure const unique_ptr<_Tuple> _FnVals(static_cast<_Tuple*>(_RawVals)); - _Tuple& _Tup = *(_FnVals.get()); // avoid ADL, handle incomplete types + _Tuple& _Tup = *_FnVals.get(); // avoid ADL, handle incomplete types _STD invoke(_STD move(_STD get<_Indices>(_Tup))...); _Cnd_do_broadcast_at_thread_exit(); // TRANSITION, ABI return 0; @@ -311,7 +311,7 @@ public: jthread& operator=(jthread&& _Other) noexcept { // note: the standard specifically disallows making self-move-assignment a no-op here - // N4917 33.4.4.2 [thread.jthread.cons]/13 + // N4917 33.4.4.2 [thread.jthread.cons]/12 // Effects: If joinable() is true, calls request_stop() and then join(). Assigns the state // of x to *this and sets x to a default constructed state. _Try_cancel_and_join(); diff --git a/stl/inc/type_traits b/stl/inc/type_traits index a4eb18d0b1..e903bc060f 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1271,7 +1271,7 @@ using _Copy_cv = // N4917 21.3.8.7 [meta.trans.other]/2.3 typename _Copy_cv_impl<_From>::template _Apply<_To>; template -struct _Add_qualifiers { // _Add_qualifiers::template _Apply is XREF(A) from N4917 21.3.8.7 [meta.trans.other]/2.1 +struct _Add_qualifiers { // _Add_qualifiers::template _Apply is XREF(A) from N4917 21.3.8.7 [meta.trans.other]/2.2 template using _Apply = _Copy_cv<_Ty1, _Ty2>; }; @@ -1858,7 +1858,7 @@ struct _Refwrap_has_ctor_from : false_type {}; template struct _Refwrap_has_ctor_from<_Ty, _Uty, void_t(_STD declval<_Uty>()))>> - : true_type {}; // qualified: avoid ADL, handle incomplete types + : true_type {}; // _STD _Refwrap_ctor_fun is qualified: avoid ADL, handle incomplete types template class reference_wrapper