[libcxx-commits] [libcxx] [libc++] Make `std::reference_constructs_from_temporary` SFINAE friendly when the 1st template argument is not a reference type (PR #206679)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 1 07:01:59 PDT 2026


================
@@ -11,28 +11,50 @@
 
 #include <__config>
 #include <__type_traits/integral_constant.h>
+#include <__type_traits/is_reference.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 2300
+
+// A non-reference type can never bind to a temporary, so the result is always `false` for such a
+// `_Tp`. We short-circuit before reaching the builtin because Clang's `__reference_constructs_from_temporary`
+// eagerly instantiates the construction of `_Up` (including the element's constructor exception
+// specification) even when `_Tp` is not a reference, which can hard-error on misbehaved types.
+//
+// https://godbolt.org/z/4xz1ozKev
+//
+// TODO: Clang 23 fix this builtin, remove this guard once all supported clang versions include this fix.
+template <class _Tp, class _Up, bool = is_reference<_Tp>::value>
+inline const bool __reference_constructs_from_temporary_v = false;
+
+template <class _Tp, class _Up>
+inline const bool __reference_constructs_from_temporary_v<_Tp, _Up, true> =
+    __reference_constructs_from_temporary(_Tp, _Up);
----------------
Kim-J-Smith wrote:

How about this:

```cpp
template <class _Tp>
concept __complete_or_unbounded =
    requires { sizeof(_Tp); } && is_object_v<remove_reference_t<_Tp>>
    || is_void_v<_Tp> || is_unbounded_array_v<_Tp>;

template <class _Tp, class _Up, bool = !is_reference_v<_Tp>
                                       && __complete_or_unbounded<_Tp>
                                       && __complete_or_unbounded<_Up>>
inline const bool __reference_constructs_from_temporary_v = false;

template <class _Tp, class _Up>
inline const bool __reference_constructs_from_temporary_v<_Tp, _Up, false> =
    __reference_constructs_from_temporary(_Tp, _Up);
```

See https://godbolt.org/z/Tnb7eT1jf

https://github.com/llvm/llvm-project/pull/206679


More information about the libcxx-commits mailing list