[libcxx-commits] [libcxx] [libc++] Use `__reference_constructs_from_temporary` if eligible (PR #141916)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Thu May 29 02:19:55 PDT 2025


https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/141916

>From 417b08ace5e0703fb0dbea2ba703cc182131b9cd Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Thu, 29 May 2025 17:19:36 +0800
Subject: [PATCH] [libc++] Use `__reference_constructs_from_temporary` if
 eligible

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.
---
 libcxx/include/tuple                                  |  4 +++-
 .../PR20855_tuple_ref_binding_diagnostics.verify.cpp  |  2 +-
 .../PR20855_tuple_ref_binding_diagnostics.pass.cpp    | 11 ++++++-----
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 8dd62ae624f5e..9aacde40b7be0 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);
+#    elif __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 at 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>



More information about the libcxx-commits mailing list