diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index d0c73410526..3f1624f40b4 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -281,6 +281,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    return is_convertible_v<_U2, _T2>;
 	  return false;
 	}
+
+      // True if construction from _U1 and _U2 would create a dangling ref.
+      template<typename _U1, typename _U2>
+	static constexpr bool
+	_S_dangles()
+	{
+#if __has_builtin(__reference_constructs_from_temporary)
+	  if constexpr (__reference_constructs_from_temporary(_T1, _U1&&))
+	    return true;
+	  else
+	    return __reference_constructs_from_temporary(_T2, _U2&&);
+#else
+	  return false;
+#endif
+	}
       /// @endcond
 
     public:
@@ -295,25 +310,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       /// Constructor accepting two values of arbitrary types
       template<typename _U1, typename _U2>
-	requires (_S_constructible<_U1, _U2>())
+	requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
 	constexpr explicit(!_S_convertible<_U1, _U2>())
 	pair(_U1&& __x, _U2&& __y)
 	noexcept(_S_nothrow_constructible<_U1, _U2>())
 	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
 	{ }
 
+      template<typename _U1, typename _U2>
+	requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
+	constexpr explicit(!_S_convertible<_U1, _U2>())
+	pair(_U1&&, _U2&&) = delete;
+
       /// Converting constructor from a const `pair<U1, U2>` lvalue
       template<typename _U1, typename _U2>
 	requires (_S_constructible<const _U1&, const _U2&>())
+	  && (!_S_dangles<_U1, _U2>())
 	constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
 	pair(const pair<_U1, _U2>& __p)
 	noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
 	: first(__p.first), second(__p.second)
 	{ }
 
+      template<typename _U1, typename _U2>
+	requires (_S_constructible<const _U1&, const _U2&>())
+	      && (_S_dangles<const _U1&, const _U2&>())
+	constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
+	pair(const pair<_U1, _U2>&) = delete;
+
       /// Converting constructor from a non-const `pair<U1, U2>` rvalue
       template<typename _U1, typename _U2>
-	requires (_S_constructible<_U1, _U2>())
+	requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
 	constexpr explicit(!_S_convertible<_U1, _U2>())
 	pair(pair<_U1, _U2>&& __p)
 	noexcept(_S_nothrow_constructible<_U1, _U2>())
@@ -321,25 +348,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  second(std::forward<_U2>(__p.second))
 	{ }
 
+      template<typename _U1, typename _U2>
+	requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
+	constexpr explicit(!_S_convertible<_U1, _U2>())
+	pair(pair<_U1, _U2>&&) = delete;
+
 #if __cplusplus > 202002L
       /// Converting constructor from a non-const `pair<U1, U2>` lvalue
       template<typename _U1, typename _U2>
-	requires (_S_constructible<_U1&, _U2&>())
+	requires (_S_constructible<_U1&, _U2&>()) && (!_S_dangles<_U1&, _U2&>())
 	constexpr explicit(!_S_convertible<_U1&, _U2&>())
 	pair(pair<_U1, _U2>& __p)
 	noexcept(_S_nothrow_constructible<_U1&, _U2&>())
 	: first(__p.first), second(__p.second)
 	{ }
 
+      template<typename _U1, typename _U2>
+	requires (_S_constructible<_U1&, _U2&>()) && (_S_dangles<_U1&, _U2&>())
+	constexpr explicit(!_S_convertible<_U1&, _U2&>())
+	pair(pair<_U1, _U2>&) = delete;
+
       /// Converting constructor from a const `pair<U1, U2>` rvalue
       template<typename _U1, typename _U2>
 	requires (_S_constructible<const _U1, const _U2>())
+	  && (!_S_dangles<const _U1, const _U2>())
 	constexpr explicit(!_S_convertible<const _U1, const _U2>())
 	pair(const pair<_U1, _U2>&& __p)
 	noexcept(_S_nothrow_constructible<const _U1, const _U2>())
 	: first(std::forward<const _U1>(__p.first)),
 	  second(std::forward<const _U2>(__p.second))
 	{ }
+
+      template<typename _U1, typename _U2>
+	requires (_S_constructible<const _U1, const _U2>())
+	  && (_S_dangles<const _U1, const _U2>())
+	constexpr explicit(!_S_convertible<const _U1, const _U2>())
+	pair(const pair<_U1, _U2>&&) = delete;
 #endif // C++23
 
   private:
@@ -463,6 +507,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else // !__cpp_lib_concepts
       // C++11/14/17 implementation using enable_if, partially constexpr.
 
+      /// @cond undocumented
+      // Error if construction from _U1 and _U2 would create a dangling ref.
+#if __has_builtin(__reference_constructs_from_temporary) \
+      && defined _GLIBCXX_DEBUG
+# define __glibcxx_no_dangling_refs(_U1, _U2) \
+  static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
+	       && !__reference_constructs_from_temporary(_T2, _U2), \
+		"std::pair constructor creates a dangling reference")
+#else
+# define __glibcxx_no_dangling_refs(_U1, _U2)
+#endif
+      /// @endcond
+
       /** The default constructor creates @c first and @c second using their
        *  respective default constructors.  */
       template <typename _U1 = _T1,
@@ -525,8 +582,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	                 && _PCCFP<_U1, _U2>::template
 			   _ImplicitlyConvertiblePair<_U1, _U2>(),
 			  bool>::type=true>
-        constexpr pair(const pair<_U1, _U2>& __p)
-        : first(__p.first), second(__p.second) { }
+	constexpr pair(const pair<_U1, _U2>& __p)
+	: first(__p.first), second(__p.second)
+	{ __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
 
       template<typename _U1, typename _U2, typename
 	       enable_if<_PCCFP<_U1, _U2>::template
@@ -535,7 +593,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			   _ImplicitlyConvertiblePair<_U1, _U2>(),
                          bool>::type=false>
 	explicit constexpr pair(const pair<_U1, _U2>& __p)
-	: first(__p.first), second(__p.second) { }
+	: first(__p.first), second(__p.second)
+	{ __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
 
 #if _GLIBCXX_USE_DEPRECATED
 #if defined(__DEPRECATED)
@@ -575,7 +634,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_GLIBCXX_DEPRECATED_PAIR_CTOR
 	constexpr
 	pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
-	: first(std::forward<_U1>(__x)), second(nullptr) { }
+	: first(std::forward<_U1>(__x)), second(nullptr)
+	{ __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
 
       template<typename _U1,
 	       __enable_if_t<__and_<__not_<is_reference<_U1>>,
@@ -587,7 +647,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_GLIBCXX_DEPRECATED_PAIR_CTOR
 	explicit constexpr
 	pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
-	: first(std::forward<_U1>(__x)), second(nullptr) { }
+	: first(std::forward<_U1>(__x)), second(nullptr)
+	{ __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
 
       template<typename _U2,
 	       __enable_if_t<__and_<is_pointer<_T1>,
@@ -599,7 +660,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_GLIBCXX_DEPRECATED_PAIR_CTOR
 	constexpr
 	pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
-	: first(nullptr), second(std::forward<_U2>(__y)) { }
+	: first(nullptr), second(std::forward<_U2>(__y))
+	{ __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
 
       template<typename _U2,
 	       __enable_if_t<__and_<is_pointer<_T1>,
@@ -611,7 +673,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_GLIBCXX_DEPRECATED_PAIR_CTOR
 	explicit constexpr
 	pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
-	: first(nullptr), second(std::forward<_U2>(__y)) { }
+	: first(nullptr), second(std::forward<_U2>(__y))
+	{ __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
 #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
 #endif
 
@@ -622,7 +685,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			   _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
                          bool>::type=true>
 	constexpr pair(_U1&& __x, _U2&& __y)
-	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
+	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
+	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
 
       template<typename _U1, typename _U2, typename
 	       enable_if<_PCCP::template
@@ -631,7 +695,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			   _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
                          bool>::type=false>
 	explicit constexpr pair(_U1&& __x, _U2&& __y)
-	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
+	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
+	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
 
 
       template<typename _U1, typename _U2, typename
@@ -642,7 +707,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                          bool>::type=true>
 	constexpr pair(pair<_U1, _U2>&& __p)
 	: first(std::forward<_U1>(__p.first)),
-	  second(std::forward<_U2>(__p.second)) { }
+	  second(std::forward<_U2>(__p.second))
+	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
 
       template<typename _U1, typename _U2, typename
 	       enable_if<_PCCFP<_U1, _U2>::template
@@ -652,7 +718,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                          bool>::type=false>
 	explicit constexpr pair(pair<_U1, _U2>&& __p)
 	: first(std::forward<_U1>(__p.first)),
-	  second(std::forward<_U2>(__p.second)) { }
+	  second(std::forward<_U2>(__p.second))
+	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
+
+#undef __glibcxx_no_dangling_refs
 
       pair&
       operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
@@ -714,7 +783,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       /// Templated constructor to convert from other pairs.
       template<typename _U1, typename _U2>
 	pair(const pair<_U1, _U2>& __p)
-	: first(__p.first), second(__p.second) { }
+	: first(__p.first), second(__p.second)
+	{
+#if __has_builtin(__reference_constructs_from_temporary)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+	  typedef int _DanglingCheck1[
+	    __reference_constructs_from_temporary(_T1, const _U1&) ? -1 : 1
+		      ];
+	  typedef int _DanglingCheck2[
+	    __reference_constructs_from_temporary(_T2, const _U2&) ? -1 : 1
+		      ];
+#pragma GCC diagnostic pop
+#endif
+	}
 #endif // C++11
     };
 
diff --git a/libstdc++-v3/testsuite/20_util/pair/dangling_ref.cc b/libstdc++-v3/testsuite/20_util/pair/dangling_ref.cc
new file mode 100644
index 00000000000..8e0c34816dd
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/dangling_ref.cc
@@ -0,0 +1,67 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-unused-variable" }
+// { dg-additional-options "-D_GLIBCXX_DEBUG" { target c++17_down } }
+
+#include <utility>
+
+#if __cplusplus >= 202002L
+// For C++20 and later, constructors are constrained to disallow dangling.
+static_assert(!std::is_constructible_v<std::pair<const int&, int>, long, int>);
+static_assert(!std::is_constructible_v<std::pair<int, const int&>, int, long>);
+static_assert(!std::is_constructible_v<std::pair<const int&, int>,
+				       std::pair<long, long>>);
+static_assert(!std::is_constructible_v<std::pair<int, const int&>,
+				       std::pair<long, long>>);
+static_assert(!std::is_constructible_v<std::pair<const int&, int>,
+				       const std::pair<long, long>&>);
+static_assert(!std::is_constructible_v<std::pair<int, const int&>,
+				       const std::pair<long, long>&>);
+#endif
+
+void
+test_binary_ctors()
+{
+  std::pair<const int&, int> p1(1L, 2);
+  // { dg-error "here" "" { target c++17_down } 24 }
+  // { dg-error "use of deleted function" "" { target c++20 } 24 }
+
+  std::pair<int, const int&> p2(1, 2L);
+  // { dg-error "here" "" { target c++17_down } 28 }
+  // { dg-error "use of deleted function" "" { target c++20 } 28 }
+
+  std::pair<const int&, const int&> p3(1L, 2L);
+  // { dg-error "here" "" { target c++17_down } 32 }
+  // { dg-error "use of deleted function" "" { target c++20 } 32 }
+}
+
+void
+test_converting_ctors()
+{
+  std::pair<long, long> p0;
+
+  std::pair<const int&, int> p1(p0);
+  // { dg-error "here" "" { target c++17_down } 42 }
+  // { dg-error "use of deleted function" "" { target c++20 } 42 }
+
+  std::pair<int, const int&> p2(p0);
+  // { dg-error "here" "" { target c++17_down } 46 }
+  // { dg-error "use of deleted function" "" { target c++20 } 46 }
+
+  std::pair<const int&, const int&> p3(p0);
+  // { dg-error "here" "" { target c++17_down } 50 }
+  // { dg-error "use of deleted function" "" { target c++20 } 50 }
+
+  std::pair<const int&, int> p4(std::move(p0));
+  // { dg-error "here" "" { target c++17_down } 54 }
+  // { dg-error "use of deleted function" "" { target c++20 } 54 }
+
+  std::pair<int, const int&> p5(std::move(p0));
+  // { dg-error "here" "" { target c++17_down } 58 }
+  // { dg-error "use of deleted function" "" { target c++20 } 58 }
+
+  std::pair<const int&, const int&> p6(std::move(p0));
+  // { dg-error "here" "" { target c++17_down } 62 }
+  // { dg-error "use of deleted function" "" { target c++20 } 62 }
+}
+
+// { dg-error "static assert.* dangling reference" "" { target { c++17_down } } 0 }
