Author: Hui Date: 2023-10-03T08:29:39+02:00 New Revision: 23988a1d82d51670e100791b8a8745e5d8457d35
URL: https://github.com/llvm/llvm-project/commit/23988a1d82d51670e100791b8a8745e5d8457d35 DIFF: https://github.com/llvm/llvm-project/commit/23988a1d82d51670e100791b8a8745e5d8457d35.diff LOG: [libc++] Fix `std::pair`'s pair-like constructor's incorrect assumption (#66585) The helper function `__pair_like_explicit_wknd` is only SFINAE-ed with `tuple_size<remove_cvref_t<_PairLike>>::value == 2`, but its function body assumes `std::get` being valid. Fixes #65620 (cherry picked from commit 054f9c55c6b4520d3feb8b4354b9b942026b5124) Added: Modified: libcxx/include/__utility/pair.h libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_like.pass.cpp Removed: ################################################################################ diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h index 43c9dbec737b016..6b8c43dbe6e4fa5 100644 --- a/libcxx/include/__utility/pair.h +++ b/libcxx/include/__utility/pair.h @@ -288,9 +288,9 @@ struct _LIBCPP_TEMPLATE_VIS pair # if _LIBCPP_STD_VER >= 23 // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. - template <class _PairLike, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2> + template <class _PairLike> _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { - if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) { + if constexpr (__pair_like<_PairLike>) { return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; } diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_like.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_like.pass.cpp index 3362a872a58579d..b93adb0ef3ebc6d 100644 --- a/libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_like.pass.cpp +++ b/libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_like.pass.cpp @@ -23,6 +23,37 @@ #include <type_traits> #include <utility> +namespace my_ns{ + +struct MyPairLike { + +template <std::size_t N> +friend int get(MyPairLike const&) +{ + return 0; +} + +}; + +} // namespace my_ns + +namespace std { + +template <> +struct tuple_size<my_ns::MyPairLike> : std::integral_constant<std::size_t, 2> {}; + +template <std::size_t N> +struct tuple_element<N, my_ns::MyPairLike> { + using type = int; +}; + +} // namespace std + +// https://github.com/llvm/llvm-project/issues/65620 +// This used to be a hard error +static_assert(!std::is_constructible_v<std::pair<int,int>, my_ns::MyPairLike const&>); + + constexpr bool test() { // Make sure construction works from array, tuple, and ranges::subrange { _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
