Repository: llvm/llvm-project
Pull request #128649: [libc++][type_traits] Implements "A type trait to detect reference binding to temporary"
Author: login: H-G-Hristov
Labels: name: libc++
description: libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
name: c++23
Created: 2025-02-25T07:47:03Z | Merged: 2025-03-08T14:20:56Z

Implements partially: [P2255R2: A type trait to detect reference binding to temporary](https://wg21.link/P2255R2)
Issue: https://github.com/llvm/llvm-project/issues/105180

https://eel.is/c++draft/meta.type.synop
https://eel.is/c++draft/meta.unary.prop

Implented type traits:
- [x] `reference_constructs_from_temporary`
- [x] `reference_converts_from_temporary`

Closes #129049

Minor drive-by tweak to `std::is_implicit_lifetime` tests.

Linked issue #129049: [libc++] P2255R2: Implement type traits
- https://wg21.link/meta.type.synop
- https://wg21.link/meta.unary.prop
  - [x] `reference_constructs_from_temporary`
  - [x] `reference_converts_from_temporary`

Diff:
diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index c45adbaec3953..a1100f0630382 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -41,6 +41,7 @@ Implemented Papers
 - N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
 - P0767R1: Deprecate POD (`Github <https://github.com/llvm/llvm-project/issues/104013>`__)
 - P1361R2: Integration of chrono with text formatting (`Github <https://github.com/llvm/llvm-project/issues/100014>`__)
+- P2255R2: A type trait to detect reference binding to temporary (implemented the type traits only) (`Github <https://github.com/llvm/llvm-project/issues/105180>`)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index bfaa63a7c224e..0f3db57788b49 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -43,7 +43,7 @@
 "`P0627R6 <https://wg21.link/P0627R6>`__","Function to mark unreachable code","2022-02 (Virtual)","|Complete|","15",""
 "`P1206R7 <https://wg21.link/P1206R7>`__","``ranges::to``: A function to convert any range to a container","2022-02 (Virtual)","|Complete|","17",""
 "`P1413R3 <https://wg21.link/P1413R3>`__","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","2022-02 (Virtual)","|Complete|","","``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but clang doesn't issue a diagnostic for deprecated using template declarations."
-"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","","",""
+"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","Implemented the type traits only."
 "`P2273R3 <https://wg21.link/P2273R3>`__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16",""
 "`P2387R3 <https://wg21.link/P2387R3>`__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19",""
 "`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","","",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ee1d7b872b364..d7c36d6b438fb 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -867,6 +867,8 @@ set(files
   __type_traits/negation.h
   __type_traits/promote.h
   __type_traits/rank.h
+  __type_traits/reference_constructs_from_temporary.h
+  __type_traits/reference_converts_from_temporary.h
   __type_traits/remove_all_extents.h
   __type_traits/remove_const.h
   __type_traits/remove_const_ref.h
diff --git a/libcxx/include/__type_traits/reference_constructs_from_temporary.h b/libcxx/include/__type_traits/reference_constructs_from_temporary.h
new file mode 100644
index 0000000000000..1666032b89bed
--- /dev/null
+++ b/libcxx/include/__type_traits/reference_constructs_from_temporary.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_constructs_from_temporary
+    : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_constructs_from_temporary_v =
+    __reference_constructs_from_temporary(_Tp, _Up);
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
diff --git a/libcxx/include/__type_traits/reference_converts_from_temporary.h b/libcxx/include/__type_traits/reference_converts_from_temporary.h
new file mode 100644
index 0000000000000..043bdbf38dada
--- /dev/null
+++ b/libcxx/include/__type_traits/reference_converts_from_temporary.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_converts_from_temporary)
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_converts_from_temporary
+    : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_converts_from_temporary_v =
+    __reference_converts_from_temporary(_Tp, _Up);
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 81c7378d9e3b8..b9964dac84acd 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -369,6 +369,14 @@ module std_core [system] {
     module negation                                   { header "__type_traits/negation.h" }
     module promote                                    { header "__type_traits/promote.h" }
     module rank                                       { header "__type_traits/rank.h" }
+    module reference_constructs_from_temporary {
+      header "__type_traits/reference_constructs_from_temporary.h"
+      export std_core.type_traits.integral_constant
+    }
+    module reference_converts_from_temporary {
+      header "__type_traits/reference_converts_from_temporary.h"
+      export std_core.type_traits.integral_constant
+    }
     module remove_all_extents                         { header "__type_traits/remove_all_extents.h" }
     module remove_const_ref                           { header "__type_traits/remove_const_ref.h" }
     module remove_const                               { header "__type_traits/remove_const.h" }
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 772e4cb876469..e09a911eeb313 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -143,6 +143,9 @@ namespace std
 
     template<class T> struct has_unique_object_representations;         // C++17
 
+    template<class T, class U> struct reference_constructs_from_temporary; // Since C++23
+    template<class T, class U> struct reference_converts_from_temporary;   // Since C++23
+
     // Relationships between types:
     template <class T, class U> struct is_same;
     template <class Base, class Derived> struct is_base_of;
@@ -382,6 +385,12 @@ namespace std
         = has_virtual_destructor<T>::value;                              // C++17
       template<class T> inline constexpr bool has_unique_object_representations_v // C++17
         = has_unique_object_representations<T>::value;
+      template<class T, class U>
+        constexpr bool reference_constructs_from_temporary_v
+          = reference_constructs_from_temporary<T, U>::value;            // Since C++23
+      template<class T, class U>
+        constexpr bool reference_converts_from_temporary_v
+          = reference_converts_from_temporary<T, U>::value;              // Since C++23
 
       // See C++14 20.10.5, type property queries
       template <class T> inline constexpr size_t alignment_of_v
@@ -523,6 +532,8 @@ namespace std
 
 #  if _LIBCPP_STD_VER >= 23
 #    include <__type_traits/is_implicit_lifetime.h>
+#    include <__type_traits/reference_constructs_from_temporary.h>
+#    include <__type_traits/reference_converts_from_temporary.h>
 #  endif
 
 #  include <version>
diff --git a/libcxx/modules/std/type_traits.inc b/libcxx/modules/std/type_traits.inc
index f544f95c7aaaa..6823c86ed153b 100644
--- a/libcxx/modules/std/type_traits.inc
+++ b/libcxx/modules/std/type_traits.inc
@@ -106,8 +106,14 @@ export namespace std {
 
   using std::has_unique_object_representations;
 
-  // using std::reference_constructs_from_temporary;
-  // using std::reference_converts_from_temporary;
+#if _LIBCPP_STD_VER >= 23
+#  if __has_builtin(__reference_constructs_from_temporary)
+  using std::reference_constructs_from_temporary;
+#  endif
+#  if __has_builtin(__reference_converts_from_temporary)
+  using std::reference_converts_from_temporary;
+#  endif
+#endif
 
   // [meta.unary.prop.query], type property queries
   using std::alignment_of;
@@ -284,8 +290,14 @@ export namespace std {
   using std::is_unbounded_array_v;
   using std::is_unsigned_v;
   using std::is_volatile_v;
-  // using std::reference_constructs_from_temporary_v;
-  // using std::reference_converts_from_temporary_v;
+#if _LIBCPP_STD_VER >= 23
+#  if __has_builtin(__reference_constructs_from_temporary)
+  using std::reference_constructs_from_temporary_v;
+#  endif
+#  if __has_builtin(__reference_converts_from_temporary)
+  using std::reference_converts_from_temporary_v;
+#  endif
+#endif
 
   // [meta.unary.prop.query], type property queries
   using std::alignment_of_v;
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
index be9149de89a6c..b51444915a5c5 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
@@ -39,9 +39,52 @@ struct A {
   A& operator=(const A&);
 };
 
-class Abstract
-{
-    virtual ~Abstract() = 0;
+class Abstract {
+  virtual ~Abstract() = 0;
 };
 
+// Types for reference_{constructs/converts}_from_temporary
+
+#if TEST_STD_VER >= 23
+
+class NonPODClass {
+public:
+  NonPODClass(int);
+};
+enum Enum { EV };
+struct Base {
+  Enum e;
+  int i;
+  float f;
+  NonPODClass* p;
+};
+// Not PODs
+struct Derived : Base {};
+
+template <class T, class RefType = T&>
+class ConvertsToRef {
+public:
+  operator RefType() const { return static_cast<RefType>(obj); }
+  mutable T obj = 42;
+};
+template <class T, class RefType = T&>
+class ConvertsToRefPrivate {
+  operator RefType() const { return static_cast<RefType>(obj); }
+  mutable T obj = 42;
+};
+
+class ExplicitConversionRvalueRef {
+public:
+  operator int();
+  explicit operator int&&();
+};
+
+class ExplicitConversionRef {
+public:
+  operator int();
+  explicit operator int&();
+};
+
+#endif
+
 #endif // TEST_META_UNARY_COMP_COMMON_H
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
index 681ad13a07dfd..24adec37431e7 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
@@ -9,7 +9,7 @@
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
 
 // These compilers don't support __builtin_is_implicit_lifetime yet.
-// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16, apple-clang-17
+// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16
 
 // <type_traits>
 
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp
index 34462f9bf0ec6..4bcb10d0b7579 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp
@@ -9,7 +9,7 @@
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
 
 // These compilers don't support __builtin_is_implicit_lifetime yet.
-// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16, apple-clang-17
+// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16
 
 // <type_traits>
 
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
new file mode 100644
index 0000000000000..5b3753c67381f
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16, clang-19.1
+
+// <type_traits>
+
+// template<class T, class U> struct reference_constructs_from_temporary;
+
+// template<class T, class U>
+// constexpr bool reference_constructs_from_temporary_v
+//   = reference_constructs_from_temporary<T, U>::value;
+
+#include <cassert>
+#include <type_traits>
+
+#include "common.h"
+#include "test_macros.h"
+
+template <typename T, typename U, bool Expected>
+constexpr void test_reference_constructs_from_temporary() {
+  assert((std::reference_constructs_from_temporary<T, U>::value == Expected));
+  assert((std::reference_constructs_from_temporary_v<T, U> == Expected));
+}
+
+constexpr bool test() {
+  test_reference_constructs_from_temporary<int&, int&, false>();
+  test_reference_constructs_from_temporary<int&, int&, false>();
+  test_reference_constructs_from_temporary<int&, int&&, false>();
+
+  test_reference_constructs_from_temporary<const int&, int&, false>();
+  test_reference_constructs_from_temporary<const int&, const int&, false>();
+  test_reference_constructs_from_temporary<const int&, int&&, false>();
+
+  test_reference_constructs_from_temporary<int&, long&, false>(); // doesn't construct
+
+  test_reference_constructs_from_temporary<const int&, long&, true>();
+  test_reference_constructs_from_temporary<const int&, long&&, true>();
+  test_reference_constructs_from_temporary<int&&, long&, true>();
+
+  assert((std::is_constructible_v<int&, ConvertsToRef<int, int&>>));
+  test_reference_constructs_from_temporary<int&, ConvertsToRef<int, int&>, false>();
+
+  assert((std::is_constructible_v<int&&, ConvertsToRef<int, int&&>>));
+  test_reference_constructs_from_temporary<int&&, ConvertsToRef<int, int&&>, false>();
+
+  assert((std::is_constructible_v<const int&, ConvertsToRef<int, const int&>>));
+  test_reference_constructs_from_temporary<int&&, ConvertsToRef<int, const int&>, false>();
+
+  assert((std::is_constructible_v<const int&, ConvertsToRef<long, long&>>));
+  test_reference_constructs_from_temporary<const int&, ConvertsToRef<long, long&>, true>();
+#ifndef TEST_COMPILER_GCC
+  test_reference_constructs_from_temporary<const int&, ConvertsToRefPrivate<long, long&>, false>();
+#endif
+
+  // Test that it doesn't accept non-reference types as input.
+  test_reference_constructs_from_temporary<int, long, false>();
+
+  test_reference_constructs_from_temporary<const int&, long, true>();
+
+  // Additional checks
+  test_reference_constructs_from_temporary<const Base&, Derived, true>();
+  test_reference_constructs_from_temporary<int&&, int, true>();
+  test_reference_constructs_from_temporary<const int&, int, true>();
+  test_reference_constructs_from_temporary<int&&, int&&, false>();
+  test_reference_constructs_from_temporary<const int&, int&&, false>();
+  test_reference_constructs_from_temporary<int&&, long&&, true>();
+  test_reference_constructs_from_temporary<int&&, long, true>();
+
+  test_reference_constructs_from_temporary<int&, ExplicitConversionRef, false>();
+  test_reference_constructs_from_temporary<const int&, ExplicitConversionRef, false>();
+  test_reference_constructs_from_temporary<int&&, ExplicitConversionRvalueRef, false>();
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
new file mode 100644
index 0000000000000..849e286c8cdab
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16, clang-18, clang-19.1
+
+// <type_traits>
+
+// template<class T, class U> struct reference_converts_from_temporary;
+
+// template<class T, class U>
+// constexpr bool reference_converts_from_temporary_v
+//   = reference_converts_from_temporary<T, U>::value;
+
+#include <cassert>
+#include <type_traits>
+
+#include "common.h"
+#include "test_macros.h"
+
+template <typename T, typename U, bool Expected>
+constexpr void test_reference_converts_from_temporary() {
+  assert((std::reference_converts_from_temporary<T, U>::value == Expected));
+  assert((std::reference_converts_from_temporary_v<T, U> == Expected));
+}
+
+constexpr bool test() {
+  test_reference_converts_from_temporary<int&, int&, false>();
+  test_reference_converts_from_temporary<int&, int&, false>();
+  test_reference_converts_from_temporary<int&, int&&, false>();
+
+  test_reference_converts_from_temporary<const int&, int&, false>();
+  test_reference_converts_from_temporary<const int&, const int&, false>();
+  test_reference_converts_from_temporary<const int&, int&&, false>();
+
+  test_reference_converts_from_temporary<int&, long&, false>(); // doesn't construct
+
+  test_reference_converts_from_temporary<const int&, long&, true>();
+  test_reference_converts_from_temporary<const int&, long&&, true>();
+  test_reference_converts_from_temporary<int&&, long&, true>();
+
+  assert((std::is_constructible_v<int&, ConvertsToRef<int, int&>>));
+  test_reference_converts_from_temporary<int&, ConvertsToRef<int, int&>, false>();
+
+  assert((std::is_constructible_v<int&&, ConvertsToRef<int, int&&>>));
+  test_reference_converts_from_temporary<int&&, ConvertsToRef<int, int&&>, false>();
+
+  assert((std::is_constructible_v<const int&, ConvertsToRef<int, const int&>>));
+  test_reference_converts_from_temporary<int&&, ConvertsToRef<int, const int&>, false>();
+
+  assert((std::is_constructible_v<const int&, ConvertsToRef<long, long&>>));
+  test_reference_converts_from_temporary<const int&, ConvertsToRef<long, long&>, true>();
+#ifndef TEST_COMPILER_GCC
+  test_reference_converts_from_temporary<const int&, ConvertsToRefPrivate<long, long&>, false>();
+#endif
+
+  // Test that it doesn't accept non-reference types as input.
+  test_reference_converts_from_temporary<int, long, false>();
+
+  test_reference_converts_from_temporary<const int&, long, true>();
+
+  // Additional checks
+  test_reference_converts_from_temporary<const Base&, Derived, true>();
+  test_reference_converts_from_temporary<int&&, int, true>();
+  test_reference_converts_from_temporary<const int&, int, true>();
+  test_reference_converts_from_temporary<int&&, int&&, false>();
+  test_reference_converts_from_temporary<const int&, int&&, false>();
+  test_reference_converts_from_temporary<int&&, long&&, true>();
+  test_reference_converts_from_temporary<int&&, long, true>();
+
+  test_reference_converts_from_temporary<int&, ExplicitConversionRef, false>();
+  test_reference_converts_from_temporary<const int&, ExplicitConversionRef, true>();
+  test_reference_converts_from_temporary<int&&, ExplicitConversionRvalueRef, true>();
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}


Reviews:
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-25T12:47:22Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-25T13:21:11Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-25T13:30:13Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-25T13:33:45Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-25T13:35:12Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T07:31:37Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T07:35:26Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T07:41:12Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T07:52:45Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T07:55:39Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T09:23:10Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-26T11:51:10Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-28T05:56:53Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-28T06:44:40Z
user: login: H-G-Hristov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-28T16:50:45Z
user: login: frederick-vs-ja
body: I think we're very near to landing this. Release notes should be added.
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T13:44:10Z
user: login: Zingam
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T17:54:01Z
user: login: Zingam
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T17:59:49Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-04T08:47:46Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T03:50:08Z
user: login: Zingam
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T06:44:35Z
user: login: Zingam
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T06:45:04Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T07:17:54Z
user: login: frederick-vs-ja
body: I think we can land this now.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T10:11:00Z
user: login: philnik777
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T10:16:24Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T10:58:32Z
user: login: frederick-vs-ja
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T01:16:28Z
user: login: frederick-vs-ja
body: LGTM!

Some stuffs in the test code are confusing, but I think we can do the cleanup later.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T10:07:24Z
user: login: philnik777
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T14:20:20Z
user: login: philnik777
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-01T07:53:40Z
user: login: Zingam
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T08:57:45Z

Review comments:
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+template <class _Tp, class _Up>
+inline constexpr bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: frederick-vs-ja
body: I think `const` can be used instead to make this usable in C++03 mode. `__reference_constructs_from_temporary_v<T, U>` will still be usable in constant expressions as it's of type `const bool`.
created_at: 2025-02-25T12:39:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
user: login: frederick-vs-ja
body: I _think_ we should require Clang 18 here. GCC is still unsupported.
created_at: 2025-02-25T12:44:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: frederick-vs-ja
body: The `__reference_converts_from_temporary` intrinsic landed in clang-19. Why isn't clang-19 supported?
created_at: 2025-02-25T12:45:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: H-G-Hristov
body: It looks like `__has_builtin(__reference_converts_from_temporary)` returns `false` in Clang 19, although I think the intrinsic is available. 
https://godbolt.org/z/rjoa48caa

I thought this would be useful for implementing: https://github.com/llvm/llvm-project/pull/128213 but I am not so sure if I should rush it now.

created_at: 2025-02-25T13:21:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+template <class _Tp, class _Up>
+inline constexpr bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: H-G-Hristov
body: I might have been confused here. Do you mean the frozen C++03 headers have nothing to do with the C++03 mode?
created_at: 2025-02-25T13:30:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+template <class _Tp, class _Up>
+inline constexpr bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: frederick-vs-ja
body: I'm not sure. Perhaps the "C++03 with non-frozen headers" mode is still being tested.
created_at: 2025-02-25T13:33:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: frederick-vs-ja
body: > It looks like `__has_builtin(__reference_converts_from_temporary)` returns `false` in Clang 19, although I think the intrinsic is available.
> https://godbolt.org/z/rjoa48caa

Ah, IIUC this is #111477. Perhaps workaround should be used.
created_at: 2025-02-25T13:35:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: H-G-Hristov
body: What would be an appropriate workaround?
created_at: 2025-02-26T07:31:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
user: login: H-G-Hristov
body: If this is supposed to land before LLVM20 is released we should support Clang 18 but after that we don't. Right?
What do you mean "GCC is still unsupported"? It looks like GCC14 implemented [P2255R2](https://wg21.link/P2255R2), although I see a compilation error in our tests.
created_at: 2025-02-26T07:35:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+
+template <class _Tp, class _Up>
+inline constexpr bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: H-G-Hristov
body: You are right. This makes sense. Thanks.
created_at: 2025-02-26T07:41:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
user: login: frederick-vs-ja
body: > If this is supposed to land before LLVM20 is released we should support Clang 18 but after that we don't. Right?

Hmm... I'm not sure whether some versions of Apple Clang should be considered unsupported.

> What do you mean "GCC is still unsupported"? It looks like GCC14 implemented [P2255R2](https://wg21.link/P2255R2), although I see a compilation error in our tests.

Sorry for misleading... It seems that GCC 14 has supported these 2 intrinsics, but access control was incorrectly ignored. So perhaps we should just skip the `ConvertsToRefPrivate` cases for GCC now.
created_at: 2025-02-26T07:52:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: frederick-vs-ja
body: Maybe we should use `__has_builtin(__reference_converts_from_temporary) || (defined(_LIBCPP_COMPILER_CLANG_BASED) && __clang_major__ >= 19)` (or `18` for `__reference_constructs_from_temporary`). I'm not sure how to handle Apple Clang, though.
created_at: 2025-02-26T07:55:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: H-G-Hristov
body: AFAIK. `__has_builtin(__reference_converts_from_temporary)` should work in Clang 18, it is broken on Clang 19.1.1 (what I use right now) it should be fixed with this patch
https://github.com/llvm/llvm-project/commit/dedbdfb70daf06fc07bb4dfbec1d18af8fcef28f
What is not clear to me, was it fixed in Clang 19.1.2 or in Clang 19.1.7.

```C++
#if __has_builtin(__reference_converts_from_temporary) || (defined(_LIBCPP_COMPILER_CLANG_BASED) && (_clang_major__ >= 19 && __clang_minor__ >= 1 && __clang_patchlevel__ >= 2))
...
```
I don't have access to macOS any longer. Xcode 16.3 should be based on LLVM19 but I guess we won't get the fix before Xcode 17.
But then the above doesn't handle ANDROID I guess because Andoroid's LLVMs is XX.0.X :) and this becomes a mess.
But I guess since Android hasn't released a compatible compiler we don't need to try to handle it yet.
created_at: 2025-02-26T09:23:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android, apple-clang-15, apple-clang-16.1, apple-clang-16.2, clang-19
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: H-G-Hristov
body: https://godbolt.org/z/Y16ejofYz
created_at: 2025-02-26T11:51:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_builtin(__reference_converts_from_temporary) ||                                                              \
+    (defined(_LIBCPP_COMPILER_CLANG_BASED) && (__clang_major__ >= 19) && (__clang_minor__ >= 1) &&                     \
+     (__clang_patchlevel__ >= 2))
path: libcxx/include/__type_traits/reference_converts_from_temporary.h
user: login: frederick-vs-ja
body: I think it would be clearer to move the conditions to `<__config>` under a temporary macro.
Also, couldn't we enable the code for Clang 19.1.0? IIUC in that version `__has_builtin(__reference_converts_from_temporary)` was wrong but `__reference_converts_from_temporary` already worked.
created_at: 2025-02-28T05:56:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_builtin(__reference_converts_from_temporary) ||                                                              \
+    (defined(_LIBCPP_COMPILER_CLANG_BASED) && (__clang_major__ >= 19) && (__clang_minor__ >= 1) &&                     \
+     (__clang_patchlevel__ >= 2))
path: libcxx/include/__type_traits/reference_converts_from_temporary.h
user: login: H-G-Hristov
body: Nice idea, thank you!
created_at: 2025-02-28T06:44:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if __has_builtin(__reference_converts_from_temporary) ||                                                              \
+    (defined(_LIBCPP_COMPILER_CLANG_BASED) && (__clang_major__ >= 19) && (__clang_minor__ >= 1) &&                     \
+     (__clang_patchlevel__ >= 2))
path: libcxx/include/__type_traits/reference_converts_from_temporary.h
user: login: H-G-Hristov
body: Android Clang vs LLVM relation can be checked here (Base revision):

https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r547379/
- [clang_source_info.md](https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r547379/clang_source_info.md)

https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r536225/
- [clang_source_info.md](https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r536225/clang_source_info.md)

https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r530567/
- [clang_source_info.md](https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r530567/clang_source_info.md)
created_at: 2025-02-28T16:50:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: frederick-vs-ja
body: The macro name (and `_LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARARY_H`) looks a bit weird.
```suggestion
#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
```
created_at: 2025-03-03T13:03:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,21 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1900))
path: libcxx/include/__config
user: login: frederick-vs-ja
body: No change requested. I still think that this should be `_LIBCPP_CLANG_VER >= 1800`. But as support for Clang 18 will be dropped in LLVM 21 release, so the difference only affects CI, IIUC.
created_at: 2025-03-03T13:42:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARARY_H
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: Zingam
body: Sorry! Thanks for noticing! That's really stupid of me :)
created_at: 2025-03-03T17:54:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,21 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1900))
path: libcxx/include/__config
user: login: Zingam
body: `#if __has_builtin(__reference_constructs_from_temporary)` works correctly in Clang 18, so I think the above expresses the workaround more clearly.
https://godbolt.org/z/f8a1MG1Gq
If you think it's better to do it as you suggest. I'll do it. No problem.

I think the only case that's not handled completely currently is `__reference_constructs_from_temporary` on Android since we don't have a compiler that implements it on that platform and I suspect that the next NDK won't include the support too.
created_at: 2025-03-03T17:59:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,21 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1900))
path: libcxx/include/__config
user: login: frederick-vs-ja
body: Yeah. The current conditions look fine to me with your explanation.
created_at: 2025-03-04T08:47:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,21 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1900))
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 1
+#  else
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 0
+#  endif
+
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_converts_from_temporary) || (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1901))
path: libcxx/include/__config
user: login: frederick-vs-ja
body: I wonder why is `1901` but not `1900` used.
created_at: 2025-03-06T03:46:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android && clang-19.0, apple-clang-15, apple-clang-16, clang-18
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: frederick-vs-ja
body: Is the `android && clang-19.0` configuration not using a "true" Clang 19? I think this configuration should be supported.
created_at: 2025-03-06T03:49:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,21 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1900))
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 1
+#  else
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 0
+#  endif
+
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_converts_from_temporary) || (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1901))
path: libcxx/include/__config
user: login: Zingam
body: Android Clang reports for example as Clang 19.0. It gets branched off `main` in between official LLVM releases with cherry-picked commits, therefore Clang 19.0 could have some features of Clang 19.1, which were committed to `main` before it got branched off. In our case:
- Android Clang 19.0 is missing `__reference_converts_from_temporary`
- Android Clang 20.0 is missing `__has_builtin(__reference_{constructs|converts|_from_temporary)` fixes

I updated the macro to make this clearer. I hope that this is no longer confusing.

created_at: 2025-03-06T06:44:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android && clang-19.0, apple-clang-15, apple-clang-16, clang-18
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
user: login: Zingam
body: Please check the comment above: https://github.com/llvm/llvm-project/pull/128649#discussion_r1982780610
created_at: 2025-03-06T06:45:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,21 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1900))
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 1
+#  else
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 0
+#  endif
+
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_converts_from_temporary) || (defined(_LIBCPP_CLANG_VER) && (_LIBCPP_CLANG_VER >= 1901))
path: libcxx/include/__config
user: login: frederick-vs-ja
body: Thanks for the information! I just remembered `__reference_converts_from_temporary` is implemented far earlier than the branching of LLVM 19.x, but according to your information, it seems that Android Clang 19.0/20.0 are more similar to the previous version of Clang (18/19) at branching.
created_at: 2025-03-06T07:17:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1215,6 +1215,24 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) &&                                                                                   \
+       ((!defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1901) || (defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1900)))
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 1
+#  else
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 0
+#  endif
path: libcxx/include/__config
user: login: philnik777
body: This should just be `__has_builtin(__reference_constructs_from_temporary)`. 99% of people use the same version of Clang and libc++, and this is way too complicated of a condition compared to what we gain.
created_at: 2025-03-06T10:14:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
+
+template <class _Tp, class _Up>
+const bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: philnik777
body: We don't need to introduce private names if we don't actually use them.
created_at: 2025-03-06T10:16:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
+
+template <class _Tp, class _Up>
+const bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: frederick-vs-ja
body: Hmm, it seems better to drop the private names for now. We can still add them when implementing [LWG4148](https://cplusplus.github.io/LWG/issue4148) (in old modes). CC @elhewaty.
created_at: 2025-03-06T10:58:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -524,6 +533,9 @@ namespace std
 #  if _LIBCPP_STD_VER >= 23
 #    include <__type_traits/is_implicit_lifetime.h>
 #  endif
+// C++23 but private declarations are available in previous standards.
+#  include <__type_traits/reference_constructs_from_temporary.h>
+#  include <__type_traits/reference_converts_from_temporary.h>
path: libcxx/include/type_traits
user: login: frederick-vs-ja
body: I think at this moment we should guard this with `#  if _LIBCPP_STD_VER >= 23`. Let's defer the exposure of private declarations to the PR for LWG4148.
created_at: 2025-03-07T01:16:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -39,9 +39,51 @@ struct A {
   A& operator=(const A&);
 };
 
-class Abstract
-{
-    virtual ~Abstract() = 0;
+class Abstract {
+  virtual ~Abstract() = 0;
 };
 
+// Types for reference_{constructs/converts}_from_temporary
+
+#if TEST_STD_VER >= 23
+
+struct NonPOD {
+  NonPOD(int);
+};
+enum Enum { EV };
+struct POD {
+  Enum e;
+  int i;
+  float f;
+  NonPOD* p;
+};
+// Not PODs
+struct Derives : POD {};
path: libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
user: login: frederick-vs-ja
body: These type names are confusing. Perhaps we only want to use `Base` and `Derived`.
created_at: 2025-03-07T10:06:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_constructs_from_temporary
+    : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_constructs_from_temporary_v =
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: philnik777
body: @Zingam It looks like you forgot to add tests for the `_LIBCPP_NO_SPECIALIZATIONS` annotations. Could you add them in a follow-up PR?
created_at: 2025-04-01T07:53:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_constructs_from_temporary
+    : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_constructs_from_temporary_v =
path: libcxx/include/__type_traits/reference_constructs_from_temporary.h
user: login: Zingam
body: Thanks! I'll do it.
created_at: 2025-04-02T08:57:45Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-02-25T07:50:23Z
body: <!--LLVM CODE FORMAT COMMENT: {clang-format}-->

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.
author_association: NONE
user: login: H-G-Hristov
created_at: 2025-03-05T05:40:17Z
body: > I think we're very near to landing this. Release notes should be added.

I did a few  changes:
- Added a note to Release Notes.
- Updated the code and tests for Android NDK r29, which was just released: https://github.com/android/ndk/wiki/Changelog-r29. The compiler is: https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/refs/heads/main/clang-r547379/ and reports as Clang 20.0, which features `__reference_converts_from_temporary` but not the fix for `__has_builtin(__reference_converts_from_temporary)`. With the latest change this upcoming version should be handled now too.
author_association: CONTRIBUTOR
user: login: llvmbot
created_at: 2025-03-06T10:12:59Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Hristo Hristov (H-G-Hristov)

<details>
<summary>Changes</summary>

Implements partially: [P2255R2: A type trait to detect reference binding to temporary](https://wg21.link/P2255R2)
Issue: https://github.com/llvm/llvm-project/issues/105180

https://eel.is/c++draft/meta.type.synop
https://eel.is/c++draft/meta.unary.prop

Implented type traits:
- [x] `reference_constructs_from_temporary`
- [x] `reference_converts_from_temporary`

According to https://github.com/llvm/llvm-project/issues/111477 `__has_builtin(`reference_{constructs|converts|_from_temporary) was broken in Clang 19.1.0 and it was fixed in [Clang 19.1.2](https://github.com/llvm/llvm-project/pull/111660#issuecomment-2479496809) with https://github.com/llvm/llvm-project/commit/dedbdfb70daf06fc07bb4dfbec1d18af8fcef28f. Workarounds were implemented and test for unsupported compilers disabled.

Closes #<!-- -->129049

Minor drive-by tweak to `std::is_implicit_lifetime` tests.

---

Patch is 22.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128649.diff


14 Files Affected:

- (modified) libcxx/docs/ReleaseNotes/21.rst (+1) 
- (modified) libcxx/docs/Status/Cxx23Papers.csv (+1-1) 
- (modified) libcxx/include/CMakeLists.txt (+2) 
- (modified) libcxx/include/__config (+18) 
- (added) libcxx/include/__type_traits/reference_constructs_from_temporary.h (+42) 
- (added) libcxx/include/__type_traits/reference_converts_from_temporary.h (+42) 
- (modified) libcxx/include/module.modulemap (+8) 
- (modified) libcxx/include/type_traits (+12) 
- (modified) libcxx/modules/std/type_traits.inc (+16-4) 
- (modified) libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h (+45-3) 
- (modified) libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp (+1-1) 
- (modified) libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp (+1-1) 
- (added) libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp (+90) 
- (added) libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp (+90) 


``````````diff
diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index f45a448e52cc0..e47883cb03f88 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -40,6 +40,7 @@ Implemented Papers
 
 - N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
 - P1361R2: Integration of chrono with text formatting (`Github <https://github.com/llvm/llvm-project/issues/100014>`__)
+- P2255R2: A type trait to detect reference binding to temporary (implemented the type traits only) (`Github <https://github.com/llvm/llvm-project/issues/105180>`)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index bfaa63a7c224e..0f3db57788b49 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -43,7 +43,7 @@
 "`P0627R6 <https://wg21.link/P0627R6>`__","Function to mark unreachable code","2022-02 (Virtual)","|Complete|","15",""
 "`P1206R7 <https://wg21.link/P1206R7>`__","``ranges::to``: A function to convert any range to a container","2022-02 (Virtual)","|Complete|","17",""
 "`P1413R3 <https://wg21.link/P1413R3>`__","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","2022-02 (Virtual)","|Complete|","","``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but clang doesn't issue a diagnostic for deprecated using template declarations."
-"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","","",""
+"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","Implemented the type traits only."
 "`P2273R3 <https://wg21.link/P2273R3>`__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16",""
 "`P2387R3 <https://wg21.link/P2387R3>`__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19",""
 "`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","","",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ee1d7b872b364..d7c36d6b438fb 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -867,6 +867,8 @@ set(files
   __type_traits/negation.h
   __type_traits/promote.h
   __type_traits/rank.h
+  __type_traits/reference_constructs_from_temporary.h
+  __type_traits/reference_converts_from_temporary.h
   __type_traits/remove_all_extents.h
   __type_traits/remove_const.h
   __type_traits/remove_const_ref.h
diff --git a/libcxx/include/__config b/libcxx/include/__config
index c8224b07a6b81..216b1251b766d 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1215,6 +1215,24 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
 #  endif
 
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_constructs_from_temporary) ||                                                          \
+      (defined(_LIBCPP_CLANG_VER) &&                                                                                   \
+       ((!defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1901) || (defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1900)))
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 1
+#  else
+#    define _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY 0
+#  endif
+
+// TODO(LLVM 22): Remove this macro once LLVM19 support ends.
+#  if __has_builtin(__reference_converts_from_temporary) ||                                                            \
+      (defined(_LIBCPP_CLANG_VER) &&                                                                                   \
+       ((!defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1901) || (defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 2000)))
+#    define _LIBCPP_HAS_REFERENCE_CONVERTS_FROM_TEMPORARY 1
+#  else
+#    define _LIBCPP_HAS_REFERENCE_CONVERTS_FROM_TEMPORARY 0
+#  endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/__type_traits/reference_constructs_from_temporary.h b/libcxx/include/__type_traits/reference_constructs_from_temporary.h
new file mode 100644
index 0000000000000..5efb1280d9d05
--- /dev/null
+++ b/libcxx/include/__type_traits/reference_constructs_from_temporary.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
+
+template <class _Tp, class _Up>
+const bool __reference_constructs_from_temporary_v = __reference_constructs_from_temporary(_Tp, _Up);
+
+#  if _LIBCPP_STD_VER >= 23
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_constructs_from_temporary
+    : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_constructs_from_temporary_v =
+    __reference_constructs_from_temporary_v<_Tp, _Up>;
+
+#  endif
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY_H
diff --git a/libcxx/include/__type_traits/reference_converts_from_temporary.h b/libcxx/include/__type_traits/reference_converts_from_temporary.h
new file mode 100644
index 0000000000000..87db23934b4a9
--- /dev/null
+++ b/libcxx/include/__type_traits/reference_converts_from_temporary.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
+#define _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_HAS_REFERENCE_CONVERTS_FROM_TEMPORARY
+
+template <class _Tp, class _Up>
+const bool __reference_converts_from_temporary_v = __reference_converts_from_temporary(_Tp, _Up);
+
+#  if _LIBCPP_STD_VER >= 23
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS reference_converts_from_temporary
+    : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> {};
+
+template <class _Tp, class _Up>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_converts_from_temporary_v =
+    __reference_converts_from_temporary_v<_Tp, _Up>;
+
+#  endif
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 81c7378d9e3b8..b9964dac84acd 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -369,6 +369,14 @@ module std_core [system] {
     module negation                                   { header "__type_traits/negation.h" }
     module promote                                    { header "__type_traits/promote.h" }
     module rank                                       { header "__type_traits/rank.h" }
+    module reference_constructs_from_temporary {
+      header "__type_traits/reference_constructs_from_temporary.h"
+      export std_core.type_traits.integral_constant
+    }
+    module reference_converts_from_temporary {
+      header "__type_traits/reference_converts_from_temporary.h"
+      export std_core.type_traits.integral_constant
+    }
     module remove_all_extents                         { header "__type_traits/remove_all_extents.h" }
     module remove_const_ref                           { header "__type_traits/remove_const_ref.h" }
     module remove_const                               { header "__type_traits/remove_const.h" }
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index ffcddb0176615..25020213bacfb 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -143,6 +143,9 @@ namespace std
 
     template<class T> struct has_unique_object_representations;         // C++17
 
+    template<class T, class U> struct reference_constructs_from_temporary; // Since C++23
+    template<class T, class U> struct reference_converts_from_temporary;   // Since C++23
+
     // Relationships between types:
     template <class T, class U> struct is_same;
     template <class Base, class Derived> struct is_base_of;
@@ -382,6 +385,12 @@ namespace std
         = has_virtual_destructor<T>::value;                              // C++17
       template<class T> inline constexpr bool has_unique_object_representations_v // C++17
         = has_unique_object_representations<T>::value;
+      template<class T, class U>
+        constexpr bool reference_constructs_from_temporary_v
+          = reference_constructs_from_temporary<T, U>::value;            // Since C++23
+      template<class T, class U>
+        constexpr bool reference_converts_from_temporary_v
+          = reference_converts_from_temporary<T, U>::value;              // Since C++23
 
       // See C++14 20.10.5, type property queries
       template <class T> inline constexpr size_t alignment_of_v
@@ -524,6 +533,9 @@ namespace std
 #  if _LIBCPP_STD_VER >= 23
 #    include <__type_traits/is_implicit_lifetime.h>
 #  endif
+// C++23 but private declarations are available in previous standards.
+#  include <__type_traits/reference_constructs_from_temporary.h>
+#  include <__type_traits/reference_converts_from_temporary.h>
 
 #  include <version>
 
diff --git a/libcxx/modules/std/type_traits.inc b/libcxx/modules/std/type_traits.inc
index f544f95c7aaaa..d8dab686d02c6 100644
--- a/libcxx/modules/std/type_traits.inc
+++ b/libcxx/modules/std/type_traits.inc
@@ -106,8 +106,14 @@ export namespace std {
 
   using std::has_unique_object_representations;
 
-  // using std::reference_constructs_from_temporary;
-  // using std::reference_converts_from_temporary;
+#if _LIBCPP_STD_VER >= 23
+#  if _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
+  using std::reference_constructs_from_temporary;
+#  endif
+#  if _LIBCPP_HAS_REFERENCE_CONVERTS_FROM_TEMPORARY
+  using std::reference_converts_from_temporary;
+#  endif
+#endif
 
   // [meta.unary.prop.query], type property queries
   using std::alignment_of;
@@ -284,8 +290,14 @@ export namespace std {
   using std::is_unbounded_array_v;
   using std::is_unsigned_v;
   using std::is_volatile_v;
-  // using std::reference_constructs_from_temporary_v;
-  // using std::reference_converts_from_temporary_v;
+#if _LIBCPP_STD_VER >= 23
+#  if _LIBCPP_HAS_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
+  using std::reference_constructs_from_temporary_v;
+#  endif
+#  if _LIBCPP_HAS_REFERENCE_CONVERTS_FROM_TEMPORARY
+  using std::reference_converts_from_temporary_v;
+#  endif
+#endif
 
   // [meta.unary.prop.query], type property queries
   using std::alignment_of_v;
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
index be9149de89a6c..c780d457d6d88 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/common.h
@@ -39,9 +39,51 @@ struct A {
   A& operator=(const A&);
 };
 
-class Abstract
-{
-    virtual ~Abstract() = 0;
+class Abstract {
+  virtual ~Abstract() = 0;
 };
 
+// Types for reference_{constructs/converts}_from_temporary
+
+#if TEST_STD_VER >= 23
+
+struct NonPOD {
+  NonPOD(int);
+};
+enum Enum { EV };
+struct POD {
+  Enum e;
+  int i;
+  float f;
+  NonPOD* p;
+};
+// Not PODs
+struct Derives : POD {};
+
+template <class T, class RefType = T&>
+class ConvertsToRef {
+public:
+  operator RefType() const { return static_cast<RefType>(obj); }
+  mutable T obj = 42;
+};
+template <class T, class RefType = T&>
+class ConvertsToRefPrivate {
+  operator RefType() const { return static_cast<RefType>(obj); }
+  mutable T obj = 42;
+};
+
+class ExplicitConversionRvalueRef {
+public:
+  operator int();
+  explicit operator int&&();
+};
+
+class ExplicitConversionRef {
+public:
+  operator int();
+  explicit operator int&();
+};
+
+#endif
+
 #endif // TEST_META_UNARY_COMP_COMMON_H
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
index 681ad13a07dfd..24adec37431e7 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp
@@ -9,7 +9,7 @@
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
 
 // These compilers don't support __builtin_is_implicit_lifetime yet.
-// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16, apple-clang-17
+// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16
 
 // <type_traits>
 
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp
index 34462f9bf0ec6..4bcb10d0b7579 100644
--- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp
@@ -9,7 +9,7 @@
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
 
 // These compilers don't support __builtin_is_implicit_lifetime yet.
-// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16, apple-clang-17
+// UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16
 
 // <type_traits>
 
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
new file mode 100644
index 0000000000000..612e4fadd4b0b
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_constructs_from_temporary.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: apple-clang-15, apple-clang-16
+
+// <type_traits>
+
+// template<class T, class U> struct reference_constructs_from_temporary;
+
+// template<class T, class U>
+// constexpr bool reference_constructs_from_temporary_v
+//   = reference_constructs_from_temporary<T, U>::value;
+
+#include <cassert>
+#include <type_traits>
+
+#include "common.h"
+#include "test_macros.h"
+
+template <typename T, typename U, bool Expected>
+constexpr void test_reference_constructs_from_temporary() {
+  assert((std::reference_constructs_from_temporary<T, U>::value == Expected));
+  assert((std::reference_constructs_from_temporary_v<T, U> == Expected));
+}
+
+constexpr bool test() {
+  test_reference_constructs_from_temporary<int&, int&, false>();
+  test_reference_constructs_from_temporary<int&, int&, false>();
+  test_reference_constructs_from_temporary<int&, int&&, false>();
+
+  test_reference_constructs_from_temporary<const int&, int&, false>();
+  test_reference_constructs_from_temporary<const int&, const int&, false>();
+  test_reference_constructs_from_temporary<const int&, int&&, false>();
+
+  test_reference_constructs_from_temporary<int&, long&, false>(); // doesn't construct
+
+  test_reference_constructs_from_temporary<const int&, long&, true>();
+  test_reference_constructs_from_temporary<const int&, long&&, true>();
+  test_reference_constructs_from_temporary<int&&, long&, true>();
+
+  assert((std::is_constructible_v<int&, ConvertsToRef<int, int&>>));
+  test_reference_constructs_from_temporary<int&, ConvertsToRef<int, int&>, false>();
+
+  assert((std::is_constructible_v<int&&, ConvertsToRef<int, int&&>>));
+  test_reference_constructs_from_temporary<int&&, ConvertsToRef<int, int&&>, false>();
+
+  assert((std::is_constructible_v<const int&, ConvertsToRef<int, const int&>>));
+  test_reference_constructs_from_temporary<int&&, ConvertsToRef<int, const int&>, false>();
+
+  assert((std::is_constructible_v<const int&, ConvertsToRef<long, long&>>));
+  test_reference_constructs_from_temporary<const int&, ConvertsToRef<long, long&>, true>();
+#ifndef TEST_COMPILER_GCC
+  test_reference_constructs_from_temporary<const int&, ConvertsToRefPrivate<long, long&>, false>();
+#endif
+
+  // Test that it doesn't accept non-reference types as input.
+  test_reference_constructs_from_temporary<int, long, false>();
+
+  test_reference_constructs_from_temporary<const int&, long, true>();
+
+  // Additional checks
+  test_reference_constructs_from_temporary<const POD&, Derives, true>();
+  test_reference_constructs_from_temporary<int&&, int, true>();
+  test_reference_constructs_from_temporary<const int&, int, true>();
+  test_reference_constructs_from_temporary<int&&, int&&, false>();
+  test_reference_constructs_from_temporary<const int&, int&&, false>();
+  test_reference_constructs_from_temporary<int&&, long&&, true>();
+  test_reference_constructs_from_temporary<int&&, long, true>();
+
+  test_reference_constructs_from_temporary<int&, ExplicitConversionRef, false>();
+  test_reference_constructs_from_temporary<const int&, ExplicitConversionRef, false>();
+  test_reference_constructs_from_temporary<int&&, ExplicitConversionRvalueRef, false>();
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
new file mode 100644
index 0000000000000..51d9d3dcb48db
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/reference_converts_from_temporary.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// These compilers don't support std::reference_converts_from_temporary yet.
+// UNSUPPORTED: android && clang-19.0, apple-clang-15, apple-clang-16, clang-18
+
+// <type_traits>
+
+// template<class T, class U> struct reference_converts_from_temporary;
+
+// template<class T, class U>
+// constexpr bool reference_converts_from_temporary_v
+//   = reference_converts_from_temporary<T, U>::value;
+
+#include <cassert>
+#include <type_traits>
+
+#include "common.h"
+#include "test_macros.h"
+
+template <typename T, typename U, bool Expected>
+constexpr void test_reference_converts_from_temporary() {
+  assert((std::reference_converts_from_temporary<T, U>::value == Expected));
+  asse...
[truncated]

``````````

</details>

author_association: MEMBER
user: login: H-G-Hristov
created_at: 2025-03-06T17:31:38Z
body: Removed workarounds and disabled tests for unsupported compilers: 
> According to https://github.com/llvm/llvm-project/issues/111477 `__has_builtin(`reference_{constructs|converts|_from_temporary) was broken in Clang 19.1.0 and it was fixed in [Clang 19.1.2](https://github.com/llvm/llvm-project/pull/111660#issuecomment-2479496809) with https://github.com/llvm/llvm-project/commit/dedbdfb70daf06fc07bb4dfbec1d18af8fcef28f. Workarounds were implemented and test for unsupported compilers disabled.
author_association: CONTRIBUTOR
user: login: philnik777
created_at: 2025-03-06T17:35:07Z
body: If only the check was broken, can't we just drop the check entirely?
author_association: CONTRIBUTOR
user: login: H-G-Hristov
created_at: 2025-03-06T18:32:26Z
body: > If only the check was broken, can't we just drop the check entirely?

Wouldn't this cause build failures in the CI if the the intrinsic isn't available?
author_association: CONTRIBUTOR
user: login: philnik777
created_at: 2025-03-06T18:34:34Z
body: > > If only the check was broken, can't we just drop the check entirely?
> 
> Wouldn't this cause build failures in the CI if the the intrinsic isn't available?

When is it not available?
author_association: CONTRIBUTOR
user: login: H-G-Hristov
created_at: 2025-03-06T18:36:06Z
body: > > > If only the check was broken, can't we just drop the check entirely?
> > 
> > 
> > Wouldn't this cause build failures in the CI if the the intrinsic isn't available?
> 
> When is it not available?

On Arm currently, Apple Clang
author_association: CONTRIBUTOR
user: login: llvm-ci
created_at: 2025-03-08T15:21:24Z
body: LLVM Buildbot has detected a new failure on builder `sanitizer-aarch64-linux-bootstrap-ubsan` running on `sanitizer-buildbot10` while building `libcxx` at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/85/builds/6282

<details>
<summary>Here is the relevant piece of the build log for the reference</summary>

```
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using ld.lld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/ld.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 86976 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 
FAIL: LLVM-Unit :: Support/./SupportTests/47/88 (79920 of 86976)
******************** TEST 'LLVM-Unit :: Support/./SupportTests/47/88' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/unittests/Support/./SupportTests-LLVM-Unit-1753793-47-88.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=88 GTEST_SHARD_INDEX=47 /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/unittests/Support/./SupportTests
--

Script:
--
/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/unittests/Support/./SupportTests --gtest_filter=Caching.WriteAfterCommit
--
/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/unittests/Support/Caching.cpp:110: Failure
Value of: llvm::detail::TakeError(CFS->commit())
Expected: succeeded
  Actual: failed  (Failed to rename temporary file /tmp/lit-tmp-kofqsd1m/llvm_test_cache/LLVMTest-18f67a.tmp.o to /tmp/lit-tmp-kofqsd1m/llvm_test_cache/llvmcache-foo: No such file or directory
)


/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/unittests/Support/Caching.cpp:110
Value of: llvm::detail::TakeError(CFS->commit())
Expected: succeeded
  Actual: failed  (Failed to rename temporary file /tmp/lit-tmp-kofqsd1m/llvm_test_cache/LLVMTest-18f67a.tmp.o to /tmp/lit-tmp-kofqsd1m/llvm_test_cache/llvmcache-foo: No such file or directory
)



********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Slowest Tests:
--------------------------------------------------------------------------
121.92s: Clang :: Driver/fsanitize.c
83.58s: Clang :: Driver/arm-cortex-cpus-2.c
82.33s: Clang :: Driver/arm-cortex-cpus-1.c
81.90s: Clang :: Preprocessor/riscv-target-features.c
78.03s: Clang :: OpenMP/target_defaultmap_codegen_01.cpp
75.25s: Clang :: OpenMP/target_update_codegen.cpp
63.91s: Clang :: Preprocessor/aarch64-target-features.c
62.52s: Clang :: Preprocessor/arm-target-features.c
58.06s: Clang :: Driver/clang_f_opts.c
Step 11 (stage2/ubsan check) failure: stage2/ubsan check (failure)
...
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using ld.lld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/ld.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:512: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 86976 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 
FAIL: LLVM-Unit :: Support/./SupportTests/47/88 (79920 of 86976)
******************** TEST 'LLVM-Unit :: Support/./SupportTests/47/88' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/unittests/Support/./SupportTests-LLVM-Unit-1753793-47-88.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=88 GTEST_SHARD_INDEX=47 /home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/unittests/Support/./SupportTests
--

Script:
--
/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm_build_ubsan/unittests/Support/./SupportTests --gtest_filter=Caching.WriteAfterCommit
--
/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/unittests/Support/Caching.cpp:110: Failure
Value of: llvm::detail::TakeError(CFS->commit())
Expected: succeeded
  Actual: failed  (Failed to rename temporary file /tmp/lit-tmp-kofqsd1m/llvm_test_cache/LLVMTest-18f67a.tmp.o to /tmp/lit-tmp-kofqsd1m/llvm_test_cache/llvmcache-foo: No such file or directory
)


/home/b/sanitizer-aarch64-linux-bootstrap-ubsan/build/llvm-project/llvm/unittests/Support/Caching.cpp:110
Value of: llvm::detail::TakeError(CFS->commit())
Expected: succeeded
  Actual: failed  (Failed to rename temporary file /tmp/lit-tmp-kofqsd1m/llvm_test_cache/LLVMTest-18f67a.tmp.o to /tmp/lit-tmp-kofqsd1m/llvm_test_cache/llvmcache-foo: No such file or directory
)



********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Slowest Tests:
--------------------------------------------------------------------------
121.92s: Clang :: Driver/fsanitize.c
83.58s: Clang :: Driver/arm-cortex-cpus-2.c
82.33s: Clang :: Driver/arm-cortex-cpus-1.c
81.90s: Clang :: Preprocessor/riscv-target-features.c
78.03s: Clang :: OpenMP/target_defaultmap_codegen_01.cpp
75.25s: Clang :: OpenMP/target_update_codegen.cpp
63.91s: Clang :: Preprocessor/aarch64-target-features.c
62.52s: Clang :: Preprocessor/arm-target-features.c
58.06s: Clang :: Driver/clang_f_opts.c

```

</details>
author_association: NONE
user: login: frederick-vs-ja
created_at: 2025-03-14T10:42:11Z
body: I guess we need to revert the drive-by changes. Not sure whether that would be temporary.

At the time of last CI for this PR, the "macos (apple-configuration, macos-15)" configuration was using apple-clang-16. But today it changed to use apple-clang-17 and the tests for `is_implicit_lifetime` still failed.
author_association: CONTRIBUTOR