[libcxx-commits] [libcxx] [libc++] Fix `std::pair`'s pair-like constructor's incorrect assumption (PR #66585)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 18 09:33:58 PDT 2023
https://github.com/huixie90 updated https://github.com/llvm/llvm-project/pull/66585
>From ebb484e4d8ee8ef233bd56daa215e6b2ce695aab Mon Sep 17 00:00:00 2001
From: Hui <hui.xie0621 at gmail.com>
Date: Sat, 16 Sep 2023 22:27:14 +0100
Subject: [PATCH] [libc++] Fix `std::pair`'s pair-like constructor's incorrect
assumption
Fixes #65620
GitHub Issue:
https://github.com/llvm/llvm-project/issues/65620
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
https://github.com/llvm/llvm-project/blame/main/libcxx/include/__utility/pair.h#L280
---
libcxx/include/__utility/pair.h | 4 +--
.../pairs/pairs.pair/ctor.pair_like.pass.cpp | 31 +++++++++++++++++++
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index 85d2f21af2420f3..62dac6dd1da3f02 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -274,9 +274,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
{
More information about the libcxx-commits
mailing list