Skip to content

[libc++] Use __reference_constructs_from_temporary if eligible #141916

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

Conversation

frederick-vs-ja
Copy link
Contributor

Currently, libc++'s <tuple> is using the deprecated __reference_binds_to_temporary intrinsic. This PR starts to use __reference_constructs_from_temporary if possible.

It seems that __reference_constructs_from_temporary should be used via an internal type traits provided in
<__type_traits/reference_constructs_from_temporary.h>. But given the old intrinsic was directly used, this PR doesn't switch to the current convention yet.

P2255R2 is related. Although the paper indicated that constructors of tuple should be deleted in such a case.

@frederick-vs-ja frederick-vs-ja requested a review from a team as a code owner May 29, 2025 08:59
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label May 29, 2025
@llvmbot
Copy link
Member

llvmbot commented May 29, 2025

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

Changes

Currently, libc++'s &lt;tuple&gt; is using the deprecated __reference_binds_to_temporary intrinsic. This PR starts to use __reference_constructs_from_temporary if possible.

It seems that __reference_constructs_from_temporary should be used via an internal type traits provided in
&lt;__type_traits/reference_constructs_from_temporary.h&gt;. But given the old intrinsic was directly used, this PR doesn't switch to the current convention yet.

P2255R2 is related. Although the paper indicated that constructors of tuple should be deleted in such a case.


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

3 Files Affected:

  • (modified) libcxx/include/tuple (+3-1)
  • (modified) libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp (+1-1)
  • (modified) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp (+6-5)
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 8dd62ae624f5e..5aef90ac19cfe 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -310,7 +310,9 @@ class __tuple_leaf {
 
   template <class _Tp>
   static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
-#    if __has_keyword(__reference_binds_to_temporary)
+#    if __has_builtin(__reference_constructs_from_temporary)
+    return !__reference_constructs_from_temporary(_Hp, _Tp);
+#    else if __has_keyword(__reference_binds_to_temporary)
     return !__reference_binds_to_temporary(_Hp, _Tp);
 #    else
     return true;
diff --git a/libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp b/libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp
index 4a6e3095c1019..df068bf35f2e5 100644
--- a/libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp
+++ b/libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp
@@ -40,7 +40,7 @@ void F(typename CannotDeduce<std::tuple<Args...>>::type const&) {}
 
 
 void f() {
-#if TEST_HAS_BUILTIN_IDENTIFIER(__reference_binds_to_temporary)
+#if TEST_HAS_BUILTIN_IDENTIFIER(__reference_constructs_from_temporary)
   // Test that we emit our diagnostic from the library.
   // expected-error@tuple:* 8 {{Attempted construction of reference element binds to a temporary whose lifetime has ended}}
 
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp
index 463816929353b..1da967d89718f 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.pass.cpp
@@ -18,12 +18,13 @@
 #include <cassert>
 #include "test_macros.h"
 
-#if TEST_HAS_BUILTIN_IDENTIFIER(__reference_binds_to_temporary)
-# define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(__reference_binds_to_temporary(__VA_ARGS__), "")
-# define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(!__reference_binds_to_temporary(__VA_ARGS__), "")
+#if TEST_HAS_BUILTIN_IDENTIFIER(__reference_constructs_from_temporary)
+#  define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(__reference_constructs_from_temporary(__VA_ARGS__), "")
+#  define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...)                                                                    \
+    static_assert(!__reference_constructs_from_temporary(__VA_ARGS__), "")
 #else
-# define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "")
-# define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "")
+#  define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "")
+#  define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "")
 #endif
 
 template <class Tp>

@frederick-vs-ja frederick-vs-ja force-pushed the tuple-no-__reference_binds_to_temporary branch 2 times, most recently from 1609e87 to 339c9c2 Compare May 29, 2025 09:18
Currently, libc++'s `<tuple>` is using the deprecated
`__reference_binds_to_temporary` intrinsic. This PR starts to use
`__reference_constructs_from_temporary` if possible.

It seems that `__reference_constructs_from_temporary` should be used via
an internal type traits provided in
`<__type_traits/reference_constructs_from_temporary.h>`. But given the
old intrinsic was directly used, this PR doesn't switch to the current
convention yet.

P2255R2 is related. Although the paper indicated that constructors of
`tuple` should be deleted in such a case.
@frederick-vs-ja
Copy link
Contributor Author

@philnik777 @Zingam @H-G-Hristov Can we land this? (As this seems blocking proper deprecation warning of __reference_binds_to_temporary.)

@frederick-vs-ja frederick-vs-ja merged commit 437ad06 into llvm:main Jun 3, 2025
129 of 135 checks passed
@frederick-vs-ja frederick-vs-ja deleted the tuple-no-__reference_binds_to_temporary branch June 3, 2025 02:34
sallto pushed a commit to sallto/llvm-project that referenced this pull request Jun 3, 2025
…m#141916)

Currently, libc++'s `<tuple>` is using the deprecated
`__reference_binds_to_temporary` intrinsic. This PR starts to use
`__reference_constructs_from_temporary` if possible.

It seems that `__reference_constructs_from_temporary` should be used via
an internal type traits provided in
`<__type_traits/reference_constructs_from_temporary.h>`. But given the
old intrinsic was directly used, this PR doesn't switch to the current
convention yet.

P2255R2 is related. Although the paper indicated that constructors of
`tuple` should be deleted in such a case.

---------

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
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