[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 09:53:26 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:
A correction is hereby made:
```cpp
template <class _Tp, class _Up = remove_reference_t<_Tp>>
concept __complete = is_function_v<_Up> || requires { sizeof(_Tp); } && is_object_v<_Up>;
template <class _Tp>
concept __complete_or_unbounded = __complete<_Tp> || is_void_v<_Tp> || is_unbounded_array_v<_Tp>;
```
https://github.com/llvm/llvm-project/pull/206679
More information about the libcxx-commits
mailing list