[llvm-branch-commits] [libcxx] 23988a1 - [libc++] Fix `std::pair`'s pair-like constructor's incorrect assumption (#66585)

Tobias Hieta via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Oct 2 23:32:36 PDT 2023


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
   {


        


More information about the llvm-branch-commits mailing list