Skip to content

Conversation

yronglin
Copy link
Contributor

@yronglin yronglin commented Aug 9, 2025

Implement P2255R2 tuple.apply part wording for std::make_from_tuple.

Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.

Fixes #154274

…ove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.

Signed-off-by: yronglin <[email protected]>
@yronglin yronglin requested a review from a team as a code owner August 9, 2025 16:49
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 9, 2025

@llvm/pr-subscribers-libcxx

Author: None (yronglin)

Changes

Implement the following wording for std::make_from_tuple.

Mandates: If tuple_size_v&lt;remove_reference_t&lt;Tuple&gt;&gt; is 1, then reference_constructs_from_temporary_v&lt;T, decltype(get&lt;0&gt;(declval&lt;Tuple&gt;()))&gt; is false.

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

2 Files Affected:

  • (modified) libcxx/include/tuple (+11-3)
  • (added) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp (+23)
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index be30ab5b2173d..9988470102266 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -1432,6 +1432,7 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t,
     enable_if_t<is_constructible_v<_Tp, decltype(std::get<_Idx>(std::forward<_Tuple>(__t)))...>> * = nullptr)
     _LIBCPP_NOEXCEPT_RETURN(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...))
 #endif // _LIBCPP_STD_VER >= 20
+#undef _LIBCPP_NOEXCEPT_RETURN
 
 template <class _Tp, class _Tuple,
           class _Seq = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>, class = void>
@@ -1451,10 +1452,17 @@ template <class _Tp, class _Tuple>
 #else
 template <class _Tp, class _Tuple, class = enable_if_t<__can_make_from_tuple<_Tp, _Tuple>>> // strengthen
 #endif // _LIBCPP_STD_VER >= 20
+
 inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
-    _LIBCPP_NOEXCEPT_RETURN(std::__make_from_tuple_impl<_Tp>(
-        std::forward<_Tuple>(__t), make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))
-#    undef _LIBCPP_NOEXCEPT_RETURN
+  noexcept(noexcept(std::__make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
+                    make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>()))) {
+  if constexpr (tuple_size_v<remove_reference_t<_Tuple>> == 1) {
+    static_assert(!__reference_constructs_from_temporary_v<_Tp, decltype(std::get<0>(std::declval<_Tuple>()))>,
+                  "Attempted construction of reference element binds to a temporary whose lifetime has ended");
+  }
+  return std::__make_from_tuple_impl<_Tp>(
+        std::forward<_Tuple>(__t), make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>());
+}
 
 #  endif // _LIBCPP_STD_VER >= 17
 
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
new file mode 100644
index 0000000000000..0ca16088964f7
--- /dev/null
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <tuple>
+
+// template <class T, class Tuple> constexpr T make_from_tuple(Tuple&&);
+// Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false.
+
+#include <tuple>
+#include <utility>
+
+void test() {
+  // expected-error@*:* {{static assertion failed}}
+  // expected-error@*:* {{returning reference to local temporary object}}
+  std::ignore = std::make_from_tuple<const int&>(std::tuple<char>{});
+}

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

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

If we don't close this, please update the PR description to be maybe one line, definitely not four.

@yronglin yronglin changed the title [libc++] Implement std::make_from_tuple mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false. [libc++][tuple.apply] Implement P2255R2 make_from_tuple part. Aug 12, 2025
@yronglin
Copy link
Contributor Author

If we don't close this, please update the PR description to be maybe one line, definitely not four.

Sure! It was changed to a more shortly title now.

Signed-off-by: yronglin <[email protected]>
@yronglin yronglin requested a review from H-G-Hristov August 15, 2025 02:51
@H-G-Hristov
Copy link
Contributor

@yronglin It LGTM but please let a maintainer approve it. I'd also appreciate if you link this PR/commit to the sub-task for easier tracking of what's done: #130403

…ence_constructs_from_temporary

Signed-off-by: yronglin <[email protected]>
@yronglin
Copy link
Contributor Author

@yronglin It LGTM but please let a maintainer approve it. I'd also appreciate if you link this PR/commit to the sub-task for easier tracking of what's done: #130403

Thanks for your review! I have marked the sub-task tuple.apply as done in #130403.

Copy link

github-actions bot commented Aug 16, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Signed-off-by: yronglin <[email protected]>
@yronglin
Copy link
Contributor Author

The buildkite/libcxx-ci/aarch64 CI ran very long time(99% 2h), and has been killed, do you know how to rerun this test only?

@H-G-Hristov
Copy link
Contributor

The buildkite/libcxx-ci/aarch64 CI ran very long time(99% 2h), and has been killed, do you know how to rerun this test only?

I think somebody with the respective access can do it. Or just rebase and start over.

Copy link
Contributor

@frederick-vs-ja frederick-vs-ja left a comment

Choose a reason for hiding this comment

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

I slightly modified the PR description to associate this PR with the appropriate issue.

@yronglin yronglin merged commit 57bf5dd into llvm:main Aug 19, 2025
75 of 78 checks passed
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.

[libc++] P2255R2: Changes to Standard library components - tuple.apply

6 participants