Skip to content

[libc++] Fix std::pair's pair-like constructor's incorrect assumption #66585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 18, 2023

Conversation

huixie90
Copy link
Contributor

GitHub Issue:
#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

@huixie90 huixie90 requested a review from a team as a code owner September 16, 2023 21:39
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 16, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 16, 2023

@llvm/pr-subscribers-libcxx

Changes

GitHub Issue:
#65620

The helper function __pair_like_explicit_wknd is only SFINAE-ed with tuple_size&lt;remove_cvref_t&lt;_PairLike&gt;&gt;::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


Full diff: https://github.com/llvm/llvm-project/pull/66585.diff

2 Files Affected:

  • (modified) libcxx/include/__utility/pair.h (+1-1)
  • (modified) libcxx/test/std/utilities/utility/pairs/pairs.pair/ctor.pair_like.pass.cpp (+30)
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index 85d2f21af2420f3..99e4066c70fc483 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -276,7 +276,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
     // 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>
     _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..24e75563e045805 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,36 @@
 #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
   {

@huixie90 huixie90 force-pushed the pair_ctr branch 2 times, most recently from a35f1e5 to ba4c6a9 Compare September 17, 2023 14:15
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this!

In your commit message, make sure you mention Fixes #65620 and it will close the issue automatically when you merge the PR.

@ldionne ldionne self-assigned this Sep 18, 2023
Fixes llvm#65620

GitHub Issue:
llvm#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
@ldionne ldionne merged commit 054f9c5 into llvm:main Sep 18, 2023
@ldionne
Copy link
Member

ldionne commented Sep 18, 2023

FYI @huixie90 your github settings are marked as keeping your email private, which means that patches will get committed using a github-generated e-mail address instead of your own. Just a heads up in case that isn't your intention.

ZijunZhaoCCK pushed a commit to ZijunZhaoCCK/llvm-project that referenced this pull request Sep 19, 2023
…on (llvm#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 llvm#65620
tru pushed a commit that referenced this pull request Oct 3, 2023
…on (#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 054f9c5)
zahiraam pushed a commit to tahonermann/llvm-project that referenced this pull request Oct 24, 2023
…on (llvm#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 llvm#65620
zahiraam pushed a commit to tahonermann/llvm-project that referenced this pull request Oct 24, 2023
…on (llvm#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 llvm#65620
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants