[libcxx-commits] [libcxx] 30dadaa - [libc++] Implement P2273R3 (`constexpr` `unique_ptr`)

Igor Zhukov via libcxx-commits libcxx-commits at lists.llvm.org
Sat Sep 3 04:51:28 PDT 2022


Author: Igor Zhukov
Date: 2022-09-03T18:49:50+07:00
New Revision: 30dadaa2eb499395f5bef44b9e1a18db6360ad1f

URL: https://github.com/llvm/llvm-project/commit/30dadaa2eb499395f5bef44b9e1a18db6360ad1f
DIFF: https://github.com/llvm/llvm-project/commit/30dadaa2eb499395f5bef44b9e1a18db6360ad1f.diff

LOG: [libc++] Implement P2273R3 (`constexpr` `unique_ptr`)

Reviewed By: mordante, #libc

Differential Revision: https://reviews.llvm.org/D131315

Added: 
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp

Modified: 
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/docs/ReleaseNotes.rst
    libcxx/docs/Status/Cxx2b.rst
    libcxx/docs/Status/Cxx2bPapers.csv
    libcxx/include/__memory/unique_ptr.h
    libcxx/include/memory
    libcxx/include/version
    libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
    libcxx/test/support/deleter_types.h
    libcxx/test/support/test_macros.h
    libcxx/test/support/unique_ptr_test_helper.h
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 88605787ab839..8d38beb3e9adc 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -312,6 +312,8 @@ Status
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_cmath``                     *unimplemented*
     ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_memory``                    ``202202L``
+    ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_typeinfo``                  *unimplemented*
     ------------------------------------------------- -----------------
     ``__cpp_lib_forward_like``                        ``202207L``

diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 5c1585254d820..9831d03a6ec45 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -40,6 +40,7 @@ Implemented Papers
 - P2499R0 - ``string_view`` range constructor should be ``explicit``
 - P2417R2 - A more constexpr bitset
 - P2445R1 - ``std::forward_like``
+- P2273R3 - Making ``std::unique_ptr`` constexpr
 
 Improvements and New Features
 -----------------------------

diff  --git a/libcxx/docs/Status/Cxx2b.rst b/libcxx/docs/Status/Cxx2b.rst
index de891629300dd..15374949d5acf 100644
--- a/libcxx/docs/Status/Cxx2b.rst
+++ b/libcxx/docs/Status/Cxx2b.rst
@@ -37,6 +37,10 @@ Paper Status
    :header-rows: 1
    :widths: auto
 
+.. note::
+
+   .. [#note-P2273] P2273: ``make_unique_for_overwrite`` isn't done yet since `P1020` hasn't been implemented yet.
+
 .. _issues-status-cxx2b:
 
 Library Working Group Issues Status

diff  --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index cbf0db4bd794e..d4d1176eb1b9d 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -44,7 +44,7 @@
 "`P1206R7 <https://wg21.link/P1206R7>`__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","",""
 "`P1413R3 <https://wg21.link/P1413R3>`__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","",""
 "`P2255R3 <https://wg21.link/P2255R3>`__","LWG","A type trait to detect reference binding to temporary","February 2022","",""
-"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","",""
+"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Partial| [#note-P2273]_","16.0"
 "`P2387R3 <https://wg21.link/P2387R3>`__","LWG","Pipe support for user-defined range adaptors","February 2022","",""
 "`P2440R1 <https://wg21.link/P2440R1>`__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","",""
 "`P2441R2 <https://wg21.link/P2441R2>`__","LWG","``views::join_view``","February 2022","",""

diff  --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 739966ab96592..399db50ad1199 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -40,12 +40,10 @@ struct _LIBCPP_TEMPLATE_VIS default_delete {
   _LIBCPP_INLINE_VISIBILITY default_delete() {}
 #endif
   template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  default_delete(const default_delete<_Up>&,
-                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
-                     0) _NOEXCEPT {}
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete(
+      const default_delete<_Up>&, typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {}
 
-  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT {
     static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");
     static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type");
     delete __ptr;
@@ -67,13 +65,11 @@ struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
 #endif
 
   template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  default_delete(const default_delete<_Up[]>&,
-                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
+  default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
 
   template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  typename _EnableIfConvertible<_Up>::type
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type
   operator()(_Up* __ptr) const _NOEXCEPT {
     static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type");
     delete[] __ptr;
@@ -175,22 +171,17 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
   _LIBCPP_INLINE_VISIBILITY
   _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}
 
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
-  _LIBCPP_INLINE_VISIBILITY
-  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {}
+  template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT
+      : __ptr_(__p, __value_init_tag()) {}
 
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
       : __ptr_(__p, __d) {}
 
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(__p, _VSTD::move(__d)) {
+  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
+  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) {
     static_assert(!is_reference<deleter_type>::value,
                   "rvalue deleter bound to reference");
   }
@@ -200,17 +191,14 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
   _LIBCPP_INLINE_VISIBILITY
   unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
 
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
-  }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}
 
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterConvertible<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+  template <class _Up,
+            class _Ep,
+            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+            class = _EnableIfDeleterConvertible<_Ep> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
       : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
 
 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
@@ -223,19 +211,17 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
       : __ptr_(__p.release(), __value_init_tag()) {}
 #endif
 
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
     reset(__u.release());
     __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
     return *this;
   }
 
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterAssignable<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
+  template <class _Up,
+            class _Ep,
+            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+            class = _EnableIfDeleterAssignable<_Ep> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
     reset(__u.release());
     __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
     return *this;
@@ -258,58 +244,44 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
   unique_ptr& operator=(unique_ptr const&) = delete;
 #endif
 
-  _LIBCPP_INLINE_VISIBILITY
-  ~unique_ptr() { reset(); }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
 
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
     reset();
     return *this;
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  typename add_lvalue_reference<_Tp>::type
-  operator*() const {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename add_lvalue_reference<_Tp>::type operator*() const {
     return *__ptr_.first();
   }
-  _LIBCPP_INLINE_VISIBILITY
-  pointer operator->() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT {
     return __ptr_.first();
   }
-  _LIBCPP_INLINE_VISIBILITY
-  pointer get() const _NOEXCEPT {
-    return __ptr_.first();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  deleter_type& get_deleter() _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {
     return __ptr_.second();
   }
-  _LIBCPP_INLINE_VISIBILITY
-  const deleter_type& get_deleter() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
     return __ptr_.second();
   }
-  _LIBCPP_INLINE_VISIBILITY
-  explicit operator bool() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
     return __ptr_.first() != nullptr;
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  pointer release() _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
     pointer __t = __ptr_.first();
     __ptr_.first() = pointer();
     return __t;
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  void reset(pointer __p = pointer()) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT {
     pointer __tmp = __ptr_.first();
     __ptr_.first() = __p;
     if (__tmp)
       __ptr_.second()(__tmp);
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  void swap(unique_ptr& __u) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {
     __ptr_.swap(__u.__ptr_);
   }
 };
@@ -397,40 +369,36 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
   _LIBCPP_INLINE_VISIBILITY
   _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {}
 
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  explicit unique_ptr(_Pp __p) _NOEXCEPT
+  template <class _Pp,
+            bool _Dummy = true,
+            class       = _EnableIfDeleterDefaultConstructible<_Dummy>,
+            class       = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT
       : __ptr_(__p, __value_init_tag()) {}
 
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+  template <class _Pp,
+            bool _Dummy = true,
+            class       = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
+            class       = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
       : __ptr_(__p, __d) {}
 
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
+  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
       : __ptr_(nullptr, __d) {}
 
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+  template <class _Pp,
+            bool _Dummy = true,
+            class       = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
+            class       = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
       : __ptr_(__p, _VSTD::move(__d)) {
     static_assert(!is_reference<deleter_type>::value,
                   "rvalue deleter bound to reference");
   }
 
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+  template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
       : __ptr_(nullptr, _VSTD::move(__d)) {
     static_assert(!is_reference<deleter_type>::value,
                   "rvalue deleter bound to reference");
@@ -442,34 +410,27 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
   _LIBCPP_INLINE_VISIBILITY
   unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
 
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
-  }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}
 
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
     reset(__u.release());
     __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
     return *this;
   }
 
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterConvertible<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
-  }
+  template <class _Up,
+            class _Ep,
+            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+            class = _EnableIfDeleterConvertible<_Ep> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
 
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterAssignable<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr&
-  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
+  template <class _Up,
+            class _Ep,
+            class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+            class = _EnableIfDeleterAssignable<_Ep> >
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
     reset(__u.release());
     __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
     return *this;
@@ -480,85 +441,70 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
   unique_ptr& operator=(unique_ptr const&) = delete;
 #endif
 public:
-  _LIBCPP_INLINE_VISIBILITY
-  ~unique_ptr() { reset(); }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
 
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT {
     reset();
     return *this;
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  typename add_lvalue_reference<_Tp>::type
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename add_lvalue_reference<_Tp>::type
   operator[](size_t __i) const {
     return __ptr_.first()[__i];
   }
-  _LIBCPP_INLINE_VISIBILITY
-  pointer get() const _NOEXCEPT {
-    return __ptr_.first();
-  }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); }
 
-  _LIBCPP_INLINE_VISIBILITY
-  deleter_type& get_deleter() _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {
     return __ptr_.second();
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  const deleter_type& get_deleter() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
     return __ptr_.second();
   }
-  _LIBCPP_INLINE_VISIBILITY
-  explicit operator bool() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
     return __ptr_.first() != nullptr;
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  pointer release() _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT {
     pointer __t = __ptr_.first();
     __ptr_.first() = pointer();
     return __t;
   }
 
   template <class _Pp>
-  _LIBCPP_INLINE_VISIBILITY
-  typename enable_if<
-      _CheckArrayPointerConversion<_Pp>::value
-  >::type
-  reset(_Pp __p) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
+      typename enable_if< _CheckArrayPointerConversion<_Pp>::value >::type
+      reset(_Pp __p) _NOEXCEPT {
     pointer __tmp = __ptr_.first();
     __ptr_.first() = __p;
     if (__tmp)
       __ptr_.second()(__tmp);
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  void reset(nullptr_t = nullptr) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT {
     pointer __tmp = __ptr_.first();
     __ptr_.first() = nullptr;
     if (__tmp)
       __ptr_.second()(__tmp);
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  void swap(unique_ptr& __u) _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT {
     __ptr_.swap(__u.__ptr_);
   }
-
 };
 
 template <class _Tp, class _Dp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<
-    __is_swappable<_Dp>::value,
-    void
->::type
-swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
+    typename enable_if< __is_swappable<_Dp>::value, void >::type
+    swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {
+  __x.swap(__y);
+}
 
 template <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
+  return __x.get() == __y.get();
+}
 
 #if _LIBCPP_STD_VER <= 17
 template <class _T1, class _D1, class _T2, class _D2>
@@ -607,11 +553,9 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
 #endif
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
-{
-    return !__x;
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
+  return !__x;
 }
 
 #if _LIBCPP_STD_VER <= 17
@@ -641,76 +585,60 @@ operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
 #endif // _LIBCPP_STD_VER <= 17
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
-    return less<_P1>()(__x.get(), nullptr);
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
+  typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+  return less<_P1>()(__x.get(), nullptr);
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
-    return less<_P1>()(nullptr, __x.get());
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
+  typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+  return less<_P1>()(nullptr, __x.get());
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    return nullptr < __x;
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
+  return nullptr < __x;
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    return __x < nullptr;
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
+  return __x < nullptr;
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    return !(nullptr < __x);
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
+  return !(nullptr < __x);
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    return !(__x < nullptr);
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
+  return !(__x < nullptr);
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    return !(__x < nullptr);
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
+  return !(__x < nullptr);
 }
 
 template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    return !(nullptr < __x);
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) {
+  return !(nullptr < __x);
 }
 
 #if _LIBCPP_STD_VER > 17
 template <class _T1, class _D1>
-requires three_way_comparable<typename unique_ptr<_T1, _D1>::pointer>
-_LIBCPP_HIDE_FROM_ABI
-compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer>
+  requires three_way_comparable<
+      typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
+      compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer>
 operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
    return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr));
 }
@@ -736,21 +664,17 @@ struct __unique_if<_Tp[_Np]>
     typedef void __unique_array_known_bound;
 };
 
-template<class _Tp, class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __unique_if<_Tp>::__unique_single
-make_unique(_Args&&... __args)
-{
-    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
+template <class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single
+make_unique(_Args&&... __args) {
+  return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
 }
 
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __unique_if<_Tp>::__unique_array_unknown_bound
-make_unique(size_t __n)
-{
-    typedef typename remove_extent<_Tp>::type _Up;
-    return unique_ptr<_Tp>(new _Up[__n]());
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique(size_t __n) {
+  typedef typename remove_extent<_Tp>::type _Up;
+  return unique_ptr<_Tp>(new _Up[__n]());
 }
 
 template<class _Tp, class... _Args>

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 0da19ee2d8135..9776de630f148 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -406,16 +406,17 @@ template <class T>
 struct default_delete
 {
     constexpr default_delete() noexcept = default;
-    template <class U> default_delete(const default_delete<U>&) noexcept;
+    template <class U> constexpr default_delete(const default_delete<U>&) noexcept; // constexpr since C++23
 
-    void operator()(T*) const noexcept;
+    constexpr void operator()(T*) const noexcept;                                   // constexpr since C++23
 };
 
 template <class T>
 struct default_delete<T[]>
 {
     constexpr default_delete() noexcept = default;
-    void operator()(T*) const noexcept;
+    template <class U> constexpr default_delete(const default_delete <U[]>&) noexcept; // constexpr since C++23
+    constexpr void operator()(T*) const noexcept;                                      // constexpr since C++23
     template <class U> void operator()(U*) const = delete;
 };
 
@@ -429,36 +430,37 @@ public:
 
     // constructors
     constexpr unique_ptr() noexcept;
-    explicit unique_ptr(pointer p) noexcept;
-    unique_ptr(pointer p, see below d1) noexcept;
-    unique_ptr(pointer p, see below d2) noexcept;
-    unique_ptr(unique_ptr&& u) noexcept;
-    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+    constexpr explicit unique_ptr(pointer p) noexcept;           // constexpr since C++23
+    constexpr unique_ptr(pointer p, see below d1) noexcept;      // constexpr since C++23
+    constexpr unique_ptr(pointer p, see below d2) noexcept;      // constexpr since C++23
+    constexpr unique_ptr(unique_ptr&& u) noexcept;               // constexpr since C++23
+    constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
     template <class U, class E>
-        unique_ptr(unique_ptr<U, E>&& u) noexcept;
+        constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;     // constexpr since C++23
     template <class U>
-        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17
+        unique_ptr(auto_ptr<U>&& u) noexcept;                    // removed in C++17
 
     // destructor
-    ~unique_ptr();
+    constexpr ~unique_ptr();                                     // constexpr since C++23
 
     // assignment
-    unique_ptr& operator=(unique_ptr&& u) noexcept;
-    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
-    unique_ptr& operator=(nullptr_t) noexcept;
+    constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;                         // constexpr since C++23
+    template <class U, class E>
+    constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;                   // constexpr since C++23
+    constexpr unique_ptr& operator=(nullptr_t) noexcept;                              // constexpr since C++23
 
     // observers
-    typename add_lvalue_reference<T>::type operator*() const;
-    pointer operator->() const noexcept;
-    pointer get() const noexcept;
-    deleter_type& get_deleter() noexcept;
-    const deleter_type& get_deleter() const noexcept;
-    explicit operator bool() const noexcept;
+    typename constexpr add_lvalue_reference<T>::type operator*() const;               // constexpr since C++23
+    constexpr pointer operator->() const noexcept;                                    // constexpr since C++23
+    constexpr pointer get() const noexcept;                                           // constexpr since C++23
+    constexpr deleter_type& get_deleter() noexcept;                                   // constexpr since C++23
+    constexpr const deleter_type& get_deleter() const noexcept;                       // constexpr since C++23
+    constexpr explicit operator bool() const noexcept;                                // constexpr since C++23
 
     // modifiers
-    pointer release() noexcept;
-    void reset(pointer p = pointer()) noexcept;
-    void swap(unique_ptr& u) noexcept;
+    constexpr pointer release() noexcept;                                             // constexpr since C++23
+    constexpr void reset(pointer p = pointer()) noexcept;                             // constexpr since C++23
+    constexpr void swap(unique_ptr& u) noexcept;                                      // constexpr since C++23
 };
 
 template <class T, class D>
@@ -471,41 +473,45 @@ public:
 
     // constructors
     constexpr unique_ptr() noexcept;
-    explicit unique_ptr(pointer p) noexcept;
-    unique_ptr(pointer p, see below d) noexcept;
-    unique_ptr(pointer p, see below d) noexcept;
-    unique_ptr(unique_ptr&& u) noexcept;
-    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+    constexpr explicit unique_ptr(pointer p) noexcept;          // constexpr since C++23
+    constexpr unique_ptr(pointer p, see below d) noexcept;      // constexpr since C++23
+    constexpr unique_ptr(pointer p, see below d) noexcept;      // constexpr since C++23
+    constexpr unique_ptr(unique_ptr&& u) noexcept;              // constexpr since C++23
+    template <class U, class E>
+    constexpr unique_ptr(unique_ptr <U, E>&& u) noexcept;       // constexpr since C++23
+    constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
 
     // destructor
-    ~unique_ptr();
+    constexpr ~unique_ptr();                                    // constexpr since C++23
 
     // assignment
-    unique_ptr& operator=(unique_ptr&& u) noexcept;
-    unique_ptr& operator=(nullptr_t) noexcept;
+    constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;        // constexpr since C++23
+    template <class U, class E>
+    constexpr unique_ptr& operator=(unique_ptr <U, E>&& u) noexcept; // constexpr since C++23
+    constexpr unique_ptr& operator=(nullptr_t) noexcept;             // constexpr since C++23
 
     // observers
-    T& operator[](size_t i) const;
-    pointer get() const noexcept;
-    deleter_type& get_deleter() noexcept;
-    const deleter_type& get_deleter() const noexcept;
-    explicit operator bool() const noexcept;
+    constexpr T& operator[](size_t i) const;                    // constexpr since C++23
+    constexpr pointer get() const noexcept;                     // constexpr since C++23
+    constexpr deleter_type& get_deleter() noexcept;             // constexpr since C++23
+    constexpr const deleter_type& get_deleter() const noexcept; // constexpr since C++23
+    constexpr explicit operator bool() const noexcept;          // constexpr since C++23
 
     // modifiers
-    pointer release() noexcept;
-    void reset(pointer p = pointer()) noexcept;
-    void reset(nullptr_t) noexcept;
+    constexpr pointer release() noexcept;                       // constexpr since C++23
+    constexpr void reset(pointer p = pointer()) noexcept;       // constexpr since C++23
+    constexpr void reset(nullptr_t) noexcept;                   // constexpr since C++23
   template <class U> void reset(U) = delete;
-    void swap(unique_ptr& u) noexcept;
+    constexpr void swap(unique_ptr& u) noexcept;                // constexpr since C++23
 };
 
 template <class T, class D>
-    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
+    constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;                 // constexpr since C++23
 
 template <class T1, class D1, class T2, class D2>
-    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+    constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);    // constexpr since C++23
 template <class T1, class D1, class T2, class D2>
-    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);    // removed in C++20
+    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);              // removed in C++20
 template <class T1, class D1, class T2, class D2>
     bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 template <class T1, class D1, class T2, class D2>
@@ -522,34 +528,34 @@ template<class T1, class D1, class T2, class D2>
     operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);      // C++20
 
 template <class T, class D>
-    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+    constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;   // constexpr since C++23
 template <class T, class D>
-    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;     // removed in C++20
+    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;             // removed in C++20
 template <class T, class D>
-    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;     // removed in C++20
+    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;             // removed in C++20
 template <class T, class D>
-    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;     // removed in C++20
+    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;             // removed in C++20
 
 template <class T, class D>
-    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
+    constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);     // constexpr since C++23
 template <class T, class D>
-    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
+    constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y);     // constexpr since C++23
 template <class T, class D>
-    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
+    constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);    // constexpr since C++23
 template <class T, class D>
-    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
+    constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y);    // constexpr since C++23
 template <class T, class D>
-    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
+    constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);     // constexpr since C++23
 template <class T, class D>
-    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
+    constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y);     // constexpr since C++23
 template <class T, class D>
-    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
+    constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);    // constexpr since C++23
 template <class T, class D>
-    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
+    constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y);    // constexpr since C++23
 template<class T, class D>
   requires three_way_comparable<typename unique_ptr<T, D>::pointer>
   compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
-    operator<=>(const unique_ptr<T, D>& x, nullptr_t);                          // C++20
+    constexpr operator<=>(const unique_ptr<T, D>& x, nullptr_t);        // C++20, constexpr since C++23
 
 class bad_weak_ptr
     : public std::exception
@@ -557,8 +563,10 @@ class bad_weak_ptr
     bad_weak_ptr() noexcept;
 };
 
-template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
-template<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
+template<class T, class... Args>
+constexpr unique_ptr<T> make_unique(Args&&... args);                            // C++14, constexpr since C++23
+template<class T>
+constexpr unique_ptr<T> make_unique(size_t n);                                  // C++14, constexpr since C++23
 template<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
 
 template<class E, class T, class Y, class D>

diff  --git a/libcxx/include/version b/libcxx/include/version
index 3c24a6d7b9dfb..858f8849fe623 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -62,7 +62,8 @@ __cpp_lib_constexpr_complex                             201711L <complex>
 __cpp_lib_constexpr_dynamic_alloc                       201907L <memory>
 __cpp_lib_constexpr_functional                          201907L <functional>
 __cpp_lib_constexpr_iterator                            201811L <iterator>
-__cpp_lib_constexpr_memory                              201811L <memory>
+__cpp_lib_constexpr_memory                              202202L <memory>
+                                                        201811L // C++20
 __cpp_lib_constexpr_numeric                             201911L <numeric>
 __cpp_lib_constexpr_string                              201907L <string>
 __cpp_lib_constexpr_string_view                         201811L <string_view>
@@ -384,6 +385,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_byteswap                             202110L
 # define __cpp_lib_constexpr_bitset                     202207L
 // # define __cpp_lib_constexpr_cmath                      202202L
+# undef  __cpp_lib_constexpr_memory
+# define __cpp_lib_constexpr_memory                     202202L
 // # define __cpp_lib_constexpr_typeinfo                   202106L
 # define __cpp_lib_forward_like                         202207L
 // # define __cpp_lib_invoke_r                             202106L

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index dd659f6521b01..e99c75d7d20f2 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -23,6 +23,7 @@
     __cpp_lib_atomic_value_initialization         201911L [C++20]
     __cpp_lib_constexpr_dynamic_alloc             201907L [C++20]
     __cpp_lib_constexpr_memory                    201811L [C++20]
+                                                  202202L [C++2b]
     __cpp_lib_enable_shared_from_this             201603L [C++17]
     __cpp_lib_make_unique                         201304L [C++14]
     __cpp_lib_out_ptr                             202106L [C++2b]
@@ -448,8 +449,8 @@
 # ifndef __cpp_lib_constexpr_memory
 #   error "__cpp_lib_constexpr_memory should be defined in c++2b"
 # endif
-# if __cpp_lib_constexpr_memory != 201811L
-#   error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b"
+# if __cpp_lib_constexpr_memory != 202202L
+#   error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b"
 # endif
 
 # ifndef __cpp_lib_enable_shared_from_this

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index d3ac7b7dc002d..ca84e43ee2a7c 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -59,6 +59,7 @@
     __cpp_lib_constexpr_functional                 201907L [C++20]
     __cpp_lib_constexpr_iterator                   201811L [C++20]
     __cpp_lib_constexpr_memory                     201811L [C++20]
+                                                   202202L [C++2b]
     __cpp_lib_constexpr_numeric                    201911L [C++20]
     __cpp_lib_constexpr_string                     201907L [C++20]
     __cpp_lib_constexpr_string_view                201811L [C++20]
@@ -3950,8 +3951,8 @@
 # ifndef __cpp_lib_constexpr_memory
 #   error "__cpp_lib_constexpr_memory should be defined in c++2b"
 # endif
-# if __cpp_lib_constexpr_memory != 201811L
-#   error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b"
+# if __cpp_lib_constexpr_memory != 202202L
+#   error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b"
 # endif
 
 # ifndef __cpp_lib_constexpr_numeric

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
index f0ca5b0ea86f0..424da1f578452 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
@@ -31,7 +31,7 @@ struct D3 {
 };
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, int[], int>::type VT;
   {
     typedef std::unique_ptr<VT> P;
@@ -54,9 +54,18 @@ void test_basic() {
 #endif
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
index 4057534fe7df3..9a21d46e0162b 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
@@ -33,34 +33,40 @@ struct GenericDeleter {
 };
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 5 : 1;
   {
     std::unique_ptr<VT> s1(newValue<VT>(expect_alive));
     A* p = s1.get();
     std::unique_ptr<VT> s2(newValue<VT>(expect_alive));
-    assert(A::count == (expect_alive * 2));
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == (expect_alive * 2));
     s2 = std::move(s1);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(s2.get() == p);
     assert(s1.get() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     std::unique_ptr<VT, Deleter<VT> > s1(newValue<VT>(expect_alive),
                                          Deleter<VT>(5));
     A* p = s1.get();
     std::unique_ptr<VT, Deleter<VT> > s2(newValue<VT>(expect_alive));
-    assert(A::count == (expect_alive * 2));
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == (expect_alive * 2));
     s2 = std::move(s1);
     assert(s2.get() == p);
     assert(s1.get() == 0);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(s2.get_deleter().state() == 5);
     assert(s1.get_deleter().state() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     CDeleter<VT> d1(5);
     std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(expect_alive), d1);
@@ -70,23 +76,27 @@ void test_basic() {
     s2 = std::move(s1);
     assert(s2.get() == p);
     assert(s1.get() == 0);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(d1.state() == 5);
     assert(d2.state() == 5);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     std::unique_ptr<VT> s(newValue<VT>(expect_alive));
     A* p = s.get();
     s = std::move(s);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(s.get() == p);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
 template <bool IsArray>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   typedef typename std::conditional<IsArray, int[], int>::type VT;
   {
     typedef std::unique_ptr<VT> U;
@@ -118,8 +128,7 @@ void test_sfinae() {
   }
 }
 
-
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_basic</*IsArray*/ false>();
     test_sfinae<false>();
@@ -129,5 +138,14 @@ int main(int, char**) {
     test_sfinae<true>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
index e2fd0c8b34904..61a2bfbbc2e05 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
@@ -23,21 +23,20 @@
 
 template <int ID = 0>
 struct GenericDeleter {
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 
 template <int ID = 0>
 struct GenericConvertingDeleter {
-
   template <int OID>
-  GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
+  TEST_CONSTEXPR_CXX23 GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
 
   template <int OID>
-  GenericConvertingDeleter& operator=(GenericConvertingDeleter<OID> const&) {
+  TEST_CONSTEXPR_CXX23 GenericConvertingDeleter& operator=(GenericConvertingDeleter<OID> const&) {
     return *this;
   }
 
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 
 template <class T, class U>
@@ -156,9 +155,9 @@ bool checkArg(ConstTrackingDeleter<ID> const& d) {
 
 template <class From, bool AssignIsConst = false>
 struct AssignDeleter {
-  AssignDeleter() = default;
-  AssignDeleter(AssignDeleter const&) = default;
-  AssignDeleter(AssignDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 AssignDeleter()                     = default;
+  TEST_CONSTEXPR_CXX23 AssignDeleter(AssignDeleter const&) = default;
+  TEST_CONSTEXPR_CXX23 AssignDeleter(AssignDeleter&&)      = default;
 
   AssignDeleter& operator=(AssignDeleter const&) = delete;
   AssignDeleter& operator=(AssignDeleter &&) = delete;
@@ -166,34 +165,34 @@ struct AssignDeleter {
   template <class T> AssignDeleter& operator=(T&&) && = delete;
   template <class T> AssignDeleter& operator=(T&&) const && = delete;
 
-  template <class T, class = typename std::enable_if<
-      std::is_same<T&&, From>::value && !AssignIsConst
-    >::type>
-  AssignDeleter& operator=(T&&) & { return *this; }
+  template <class T, class = typename std::enable_if< std::is_same<T&&, From>::value && !AssignIsConst >::type>
+  TEST_CONSTEXPR_CXX23 AssignDeleter& operator=(T&&) & {
+    return *this;
+  }
 
-  template <class T, class = typename std::enable_if<
-      std::is_same<T&&, From>::value && AssignIsConst
-    >::type>
-  const AssignDeleter& operator=(T&&) const & { return *this; }
+  template <class T, class = typename std::enable_if< std::is_same<T&&, From>::value && AssignIsConst >::type>
+  TEST_CONSTEXPR_CXX23 const AssignDeleter& operator=(T&&) const& {
+    return *this;
+  }
 
   template <class T>
-  void operator()(T) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(T) const {}
 };
 
 template <class VT, class DDest, class DSource>
-  void doDeleterTest() {
-    using U1 = std::unique_ptr<VT, DDest>;
-    using U2 = std::unique_ptr<VT, DSource>;
-    static_assert(std::is_nothrow_assignable<U1, U2&&>::value, "");
-    typename std::decay<DDest>::type ddest;
-    typename std::decay<DSource>::type dsource;
-    U1 u1(nullptr, ddest);
-    U2 u2(nullptr, dsource);
-    u1 = std::move(u2);
+TEST_CONSTEXPR_CXX23 void doDeleterTest() {
+  using U1 = std::unique_ptr<VT, DDest>;
+  using U2 = std::unique_ptr<VT, DSource>;
+  static_assert(std::is_nothrow_assignable<U1, U2&&>::value, "");
+  typename std::decay<DDest>::type ddest;
+  typename std::decay<DSource>::type dsource;
+  U1 u1(nullptr, ddest);
+  U2 u2(nullptr, dsource);
+  u1 = std::move(u2);
 }
 
 template <bool IsArray>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
 
   { // Test that 
diff erent non-reference deleter types are allowed so long
@@ -281,9 +280,8 @@ void test_sfinae() {
   }
 }
 
-
 template <bool IsArray>
-void test_noexcept() {
+TEST_CONSTEXPR_CXX23 void test_noexcept() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   {
     typedef std::unique_ptr<const VT> APtr;
@@ -405,17 +403,28 @@ void test_deleter_value_category() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_sfinae</*IsArray*/false>();
     test_noexcept<false>();
-    test_deleter_value_category<false>();
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      test_deleter_value_category<false>();
   }
   {
     test_sfinae</*IsArray*/true>();
     test_noexcept<true>();
-    test_deleter_value_category<true>();
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      test_deleter_value_category<true>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
index 73b4634af9147..0201e9c4385a4 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
@@ -23,55 +23,58 @@
 #include "unique_ptr_test_helper.h"
 
 template <class APtr, class BPtr>
-void testAssign(APtr& aptr, BPtr& bptr) {
+TEST_CONSTEXPR_CXX23 void testAssign(APtr& aptr, BPtr& bptr) {
   A* p = bptr.get();
-  assert(A::count == 2);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 2);
   aptr = std::move(bptr);
   assert(aptr.get() == p);
   assert(bptr.get() == 0);
-  assert(A::count == 1);
-  assert(B::count == 1);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 1);
+    assert(B::count == 1);
+  }
 }
 
 template <class LHS, class RHS>
-void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {
+TEST_CONSTEXPR_CXX23 void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {
   assert(lhs.get_deleter().state() == LHSState);
   assert(rhs.get_deleter().state() == RHSState);
 }
 
 template <class T>
 struct NCConvertingDeleter {
-  NCConvertingDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter()                      = default;
   NCConvertingDeleter(NCConvertingDeleter const&) = delete;
-  NCConvertingDeleter(NCConvertingDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default;
 
   template <class U>
-  NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
 
-  void operator()(T*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}
 };
 
 template <class T>
 struct NCConvertingDeleter<T[]> {
-  NCConvertingDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter()                      = default;
   NCConvertingDeleter(NCConvertingDeleter const&) = delete;
-  NCConvertingDeleter(NCConvertingDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default;
 
   template <class U>
-  NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
 
-  void operator()(T*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}
 };
 
 struct NCGenericDeleter {
-  NCGenericDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NCGenericDeleter()                   = default;
   NCGenericDeleter(NCGenericDeleter const&) = delete;
-  NCGenericDeleter(NCGenericDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 NCGenericDeleter(NCGenericDeleter&&) = default;
 
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   using DA = NCConvertingDeleter<A>; // non-copyable deleters
   using DB = NCConvertingDeleter<B>;
   using UA = std::unique_ptr<A>;
@@ -114,15 +117,17 @@ void test_sfinae() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_sfinae();
   {
     std::unique_ptr<B> bptr(new B);
     std::unique_ptr<A> aptr(new A);
     testAssign(aptr, bptr);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
   {
     Deleter<B> del(42);
     std::unique_ptr<B, Deleter<B> > bptr(new B, std::move(del));
@@ -130,8 +135,10 @@ int main(int, char**) {
     testAssign(aptr, bptr);
     checkDeleter(aptr, bptr, 42, 0);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
   {
     CDeleter<A> adel(6);
     CDeleter<B> bdel(42);
@@ -140,8 +147,19 @@ int main(int, char**) {
     testAssign(aptr, bptr);
     checkDeleter(aptr, bptr, 42, 42);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
index 1af7eccb38c5e..f2e3f6bd9a6b5 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
@@ -20,22 +20,34 @@
 
 // test assignment from null
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 5 : 1;
   {
     std::unique_ptr<VT> s2(newValue<VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     s2 = NULL;
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
     assert(s2.get() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
index 4a44a92dd2a86..e69973a43966c 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
@@ -21,22 +21,34 @@
 // test assignment from null
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 5 : 1;
   {
     std::unique_ptr<VT> s2(newValue<VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     s2 = nullptr;
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
     assert(s2.get() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
index 7243f5857fcd1..c6fef01066462 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
@@ -15,9 +15,9 @@
 // The following constructors should not be selected by class template argument
 // deduction:
 //
-// explicit unique_ptr(pointer p)
-// unique_ptr(pointer p, const D& d) noexcept
-// unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept
+// constexpr explicit unique_ptr(pointer p) // constexpr since C++23
+// constexpr unique_ptr(pointer p, const D& d) noexcept // constexpr since C++23
+// constexpr unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept // constexpr since C++23
 
 #include <memory>
 

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
index bfe9a632c2f42..7f4c90922d6c3 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
@@ -36,12 +36,12 @@ TEST_CONSTINIT std::unique_ptr<int[]> global_static_unique_ptr_runtime;
 
 struct NonDefaultDeleter {
   NonDefaultDeleter() = delete;
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 #endif
 
 template <class ElemType>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
 #if TEST_STD_VER >= 11
   { // the constructor does not participate in overload resolution when
     // the deleter is a pointer type
@@ -51,9 +51,9 @@ void test_sfinae() {
   { // the constructor does not participate in overload resolution when
     // the deleter is not default constructible
     using Del = CDeleter<ElemType>;
-    using U1 = std::unique_ptr<ElemType, NonDefaultDeleter>;
-    using U2 = std::unique_ptr<ElemType, Del&>;
-    using U3 = std::unique_ptr<ElemType, Del const&>;
+    using U1  = std::unique_ptr<ElemType, NonDefaultDeleter>;
+    using U2  = std::unique_ptr<ElemType, Del&>;
+    using U3  = std::unique_ptr<ElemType, Del const&>;
     static_assert(!std::is_default_constructible<U1>::value, "");
     static_assert(!std::is_default_constructible<U2>::value, "");
     static_assert(!std::is_default_constructible<U3>::value, "");
@@ -62,7 +62,7 @@ void test_sfinae() {
 }
 
 template <class ElemType>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 bool test_basic() {
 #if TEST_STD_VER >= 11
   {
     using U1 = std::unique_ptr<ElemType>;
@@ -87,6 +87,8 @@ void test_basic() {
     assert(p.get() == 0);
     assert(p.get_deleter().state() == 0);
   }
+
+  return true;
 }
 
 DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
@@ -97,7 +99,7 @@ DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
   doIncompleteTypeTest<IncompleteType[], Deleter<IncompleteType[]> >(0);
 })
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_sfinae<int>();
     test_basic<int>();
@@ -107,5 +109,14 @@ int main(int, char**) {
     test_basic<int[]>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
index 5ccc5d60aeecf..318f4b18a0d1e 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
@@ -38,12 +38,12 @@
 //    'sink' should accept the unique_ptr by value. (C-1,2,4)
 
 template <class VT>
-std::unique_ptr<VT> source1() {
+TEST_CONSTEXPR_CXX23 std::unique_ptr<VT> source1() {
   return std::unique_ptr<VT>(newValue<VT>(1));
 }
 
 template <class VT>
-std::unique_ptr<VT, Deleter<VT> > source2() {
+TEST_CONSTEXPR_CXX23 std::unique_ptr<VT, Deleter<VT> > source2() {
   return std::unique_ptr<VT, Deleter<VT> >(newValue<VT>(1), Deleter<VT>(5));
 }
 
@@ -54,12 +54,12 @@ std::unique_ptr<VT, NCDeleter<VT>&> source3() {
 }
 
 template <class VT>
-void sink1(std::unique_ptr<VT> p) {
+TEST_CONSTEXPR_CXX23 void sink1(std::unique_ptr<VT> p) {
   assert(p.get() != nullptr);
 }
 
 template <class VT>
-void sink2(std::unique_ptr<VT, Deleter<VT> > p) {
+TEST_CONSTEXPR_CXX23 void sink2(std::unique_ptr<VT, Deleter<VT> > p) {
   assert(p.get() != nullptr);
   assert(p.get_deleter().state() == 5);
 }
@@ -72,7 +72,7 @@ void sink3(std::unique_ptr<VT, NCDeleter<VT>&> p) {
 }
 
 template <class ValueT>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   typedef std::unique_ptr<ValueT> U;
   { // Ensure unique_ptr is non-copyable
     static_assert((!std::is_constructible<U, U const&>::value), "");
@@ -81,7 +81,7 @@ void test_sfinae() {
 }
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<!IsArray, A, A[]>::type VT;
   const int expect_alive = IsArray ? 5 : 1;
   {
@@ -91,9 +91,11 @@ void test_basic() {
     APtr s2 = std::move(s);
     assert(s2.get() == p);
     assert(s.get() == 0);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     typedef Deleter<VT> MoveDel;
     typedef std::unique_ptr<VT, MoveDel> APtr;
@@ -105,11 +107,13 @@ void test_basic() {
     APtr s2 = std::move(s);
     assert(s2.get() == p);
     assert(s.get() == 0);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(s2.get_deleter().state() == 5);
     assert(s.get_deleter().state() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     typedef NCDeleter<VT> NonCopyDel;
     typedef std::unique_ptr<VT, NonCopyDel&> APtr;
@@ -120,25 +124,28 @@ void test_basic() {
     APtr s2 = std::move(s);
     assert(s2.get() == p);
     assert(s.get() == 0);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     d.set_state(6);
     assert(s2.get_deleter().state() == d.state());
     assert(s.get_deleter().state() == d.state());
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     sink1<VT>(source1<VT>());
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
     sink2<VT>(source2<VT>());
-    assert(A::count == 0);
-    sink3<VT>(source3<VT>());
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
 template <class VT>
-void test_noexcept() {
+TEST_CONSTEXPR_CXX23 void test_noexcept() {
 #if TEST_STD_VER >= 11
   {
     typedef std::unique_ptr<VT> U;
@@ -159,7 +166,7 @@ void test_noexcept() {
 #endif
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_basic</*IsArray*/ false>();
     test_sfinae<int>();
@@ -171,5 +178,23 @@ int main(int, char**) {
     test_noexcept<int[]>();
   }
 
+  return true;
+}
+
+template <bool IsArray>
+void test_sink3() {
+  typedef typename std::conditional<!IsArray, A, A[]>::type VT;
+  sink3<VT>(source3<VT>());
+  assert(A::count == 0);
+}
+
+int main(int, char**) {
+  test_sink3</*IsArray*/ false>();
+  test_sink3</*IsArray*/ true>();
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
index 9153f0a93b0fa..3a868626f46f9 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
@@ -23,14 +23,14 @@
 
 template <int ID = 0>
 struct GenericDeleter {
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 
 template <int ID = 0>
 struct GenericConvertingDeleter {
   template <int OID>
-  GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 
 template <class Templ, class Other>
@@ -50,37 +50,35 @@ using EnableIfSpecialization = typename std::enable_if<
 
 template <int ID>
 struct TrackingDeleter {
-  TrackingDeleter() : arg_type(&makeArgumentID<>()) {}
+  TEST_CONSTEXPR_CXX23 TrackingDeleter() : arg_type(&makeArgumentID<>()) {}
 
-  TrackingDeleter(TrackingDeleter const&)
-      : arg_type(&makeArgumentID<TrackingDeleter const&>()) {}
+  TEST_CONSTEXPR_CXX23 TrackingDeleter(TrackingDeleter const&) : arg_type(&makeArgumentID<TrackingDeleter const&>()) {}
 
-  TrackingDeleter(TrackingDeleter&&)
-      : arg_type(&makeArgumentID<TrackingDeleter &&>()) {}
+  TEST_CONSTEXPR_CXX23 TrackingDeleter(TrackingDeleter&&) : arg_type(&makeArgumentID<TrackingDeleter&&>()) {}
 
   template <class T, class = EnableIfSpecialization<TrackingDeleter, T> >
-  TrackingDeleter(T&&) : arg_type(&makeArgumentID<T&&>()) {}
+  TEST_CONSTEXPR_CXX23 TrackingDeleter(T&&) : arg_type(&makeArgumentID<T&&>()) {}
 
-  TrackingDeleter& operator=(TrackingDeleter const&) {
+  TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(TrackingDeleter const&) {
     arg_type = &makeArgumentID<TrackingDeleter const&>();
     return *this;
   }
 
-  TrackingDeleter& operator=(TrackingDeleter &&) {
+  TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(TrackingDeleter&&) {
     arg_type = &makeArgumentID<TrackingDeleter &&>();
     return *this;
   }
 
   template <class T, class = EnableIfSpecialization<TrackingDeleter, T> >
-  TrackingDeleter& operator=(T&&) {
+  TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(T&&) {
     arg_type = &makeArgumentID<T&&>();
     return *this;
   }
 
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 
 public:
-  TypeID const* reset() const {
+  TEST_CONSTEXPR_CXX23 TypeID const* reset() const {
     TypeID const* tmp = arg_type;
     arg_type = nullptr;
     return tmp;
@@ -95,9 +93,8 @@ bool checkArg(TrackingDeleter<ID> const& d) {
   return d.arg_type && *d.arg_type == makeArgumentID<ExpectT>();
 }
 
-
 template <bool IsArray>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
 
   { // Test that 
diff erent non-reference deleter types are allowed so long
@@ -144,9 +141,8 @@ void test_sfinae() {
   }
 }
 
-
 template <bool IsArray>
-void test_noexcept() {
+TEST_CONSTEXPR_CXX23 void test_noexcept() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   {
     typedef std::unique_ptr<const VT> APtr;
@@ -170,9 +166,8 @@ void test_noexcept() {
   }
 }
 
-
 template <bool IsArray>
-void test_deleter_value_category() {
+TEST_CONSTEXPR_CXX23 void test_deleter_value_category() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   using TD1 = TrackingDeleter<1>;
   using TD2 = TrackingDeleter<2>;
@@ -203,18 +198,28 @@ void test_deleter_value_category() {
   }
 }
 
-
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_sfinae</*IsArray*/false>();
     test_noexcept<false>();
-    test_deleter_value_category<false>();
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      test_deleter_value_category<false>();
   }
   {
     test_sfinae</*IsArray*/true>();
     test_noexcept<true>();
-    test_deleter_value_category<true>();
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      test_deleter_value_category<true>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
index a75ebff347036..2bd6f7511ff4f 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
@@ -33,7 +33,7 @@ struct GenericConvertingDeleter {
   void operator()(void*) const {}
 };
 
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   { // Disallow copying
     using U1 = std::unique_ptr<A[], GenericConvertingDeleter<0> >;
     using U2 = std::unique_ptr<A[], GenericConvertingDeleter<1> >;
@@ -77,9 +77,17 @@ void test_sfinae() {
   }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_sfinae();
+
+  return true;
+}
 
 int main(int, char**) {
-  test_sfinae();
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
index 4c3883ea0a419..13d40b9f6d3bc 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
@@ -29,7 +29,7 @@
 // Explicit version
 
 template <class LHS, class RHS>
-void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
+TEST_CONSTEXPR_CXX23 void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
   typedef typename LHS::deleter_type NewDel;
   static_assert(std::is_reference<NewDel>::value, "");
   rhs.get_deleter().set_state(42);
@@ -41,57 +41,61 @@ void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
 }
 
 template <class LHS, class RHS>
-void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) {
+TEST_CONSTEXPR_CXX23 void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) {
   assert(lhs.get_deleter().state() == LHSVal);
   assert(rhs.get_deleter().state() == RHSVal);
 }
 
 template <class LHS, class RHS>
-void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) {
+TEST_CONSTEXPR_CXX23 void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) {
   assert(lhs.get() == RHSVal);
   assert(rhs.get() == nullptr);
-  assert(A::count == 1);
-  assert(B::count == 1);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 1);
+    assert(B::count == 1);
+  }
 }
 
-void checkNoneAlive() {
-  assert(A::count == 0);
-  assert(B::count == 0);
+TEST_CONSTEXPR_CXX23 void checkNoneAlive() {
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
 }
 
 template <class T>
 struct NCConvertingDeleter {
-  NCConvertingDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter()                      = default;
   NCConvertingDeleter(NCConvertingDeleter const&) = delete;
-  NCConvertingDeleter(NCConvertingDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default;
 
   template <class U>
-  NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
 
-  void operator()(T*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}
 };
 
 template <class T>
 struct NCConvertingDeleter<T[]> {
-  NCConvertingDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter()                      = default;
   NCConvertingDeleter(NCConvertingDeleter const&) = delete;
-  NCConvertingDeleter(NCConvertingDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default;
 
   template <class U>
-  NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
 
-  void operator()(T*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}
 };
 
 struct NCGenericDeleter {
-  NCGenericDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NCGenericDeleter()                   = default;
   NCGenericDeleter(NCGenericDeleter const&) = delete;
-  NCGenericDeleter(NCGenericDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 NCGenericDeleter(NCGenericDeleter&&) = default;
 
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
   using DA = NCConvertingDeleter<A>; // non-copyable deleters
   using DB = NCConvertingDeleter<B>;
   using UA = std::unique_ptr<A>;
@@ -134,7 +138,7 @@ void test_sfinae() {
   }
 }
 
-void test_noexcept() {
+TEST_CONSTEXPR_CXX23 void test_noexcept() {
   {
     typedef std::unique_ptr<A> APtr;
     typedef std::unique_ptr<B> BPtr;
@@ -157,7 +161,7 @@ void test_noexcept() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_sfinae();
     test_noexcept();
@@ -245,5 +249,14 @@ int main(int, char**) {
     checkNoneAlive();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
index 0ccbf05f58a67..51e5ec732aa27 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
@@ -23,7 +23,7 @@
 #include "unique_ptr_test_helper.h"
 
 template <class VT>
-void test_pointer_ctor() {
+TEST_CONSTEXPR_CXX23 void test_pointer_ctor() {
   {
     std::unique_ptr<VT> p(0);
     assert(p.get() == 0);
@@ -36,7 +36,7 @@ void test_pointer_ctor() {
 }
 
 template <class VT>
-void test_pointer_deleter_ctor() {
+TEST_CONSTEXPR_CXX23 void test_pointer_deleter_ctor() {
   {
     std::default_delete<VT> d;
     std::unique_ptr<VT> p(0, d);
@@ -61,7 +61,7 @@ void test_pointer_deleter_ctor() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     // test_pointer_ctor<int>();
     test_pointer_deleter_ctor<int>();
@@ -71,5 +71,14 @@ int main(int, char**) {
     test_pointer_deleter_ctor<int[]>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
index 95393b677d61c..45017a03b95dd 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
@@ -10,7 +10,7 @@
 
 // unique_ptr
 
-// unique_ptr(nullptr_t);
+// constexpr unique_ptr(nullptr_t);  // constexpr since C++23
 
 #include <memory>
 #include <cassert>
@@ -18,7 +18,6 @@
 #include "test_macros.h"
 #include "unique_ptr_test_helper.h"
 
-
 #if TEST_STD_VER >= 11
 TEST_CONSTINIT std::unique_ptr<int> global_static_unique_ptr_single(nullptr);
 TEST_CONSTINIT std::unique_ptr<int[]> global_static_unique_ptr_runtime(nullptr);
@@ -30,15 +29,13 @@ struct NonDefaultDeleter {
 #endif
 
 template <class VT>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
 #if TEST_STD_VER >= 11
   {
     using U1 = std::unique_ptr<VT>;
     using U2 = std::unique_ptr<VT, Deleter<VT> >;
-    static_assert(std::is_nothrow_constructible<U1, decltype(nullptr)>::value,
-                  "");
-    static_assert(std::is_nothrow_constructible<U2, decltype(nullptr)>::value,
-                  "");
+    static_assert(std::is_nothrow_constructible<U1, decltype(nullptr)>::value, "");
+    static_assert(std::is_nothrow_constructible<U2, decltype(nullptr)>::value, "");
   }
 #endif
   {
@@ -58,7 +55,7 @@ void test_basic() {
 }
 
 template <class VT>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
 #if TEST_STD_VER >= 11
   { // the constructor does not participate in overload resolution when
     // the deleter is a pointer type
@@ -68,9 +65,9 @@ void test_sfinae() {
   { // the constructor does not participate in overload resolution when
     // the deleter is not default constructible
     using Del = CDeleter<VT>;
-    using U1 = std::unique_ptr<VT, NonDefaultDeleter>;
-    using U2 = std::unique_ptr<VT, Del&>;
-    using U3 = std::unique_ptr<VT, Del const&>;
+    using U1  = std::unique_ptr<VT, NonDefaultDeleter>;
+    using U2  = std::unique_ptr<VT, Del&>;
+    using U3  = std::unique_ptr<VT, Del const&>;
     static_assert(!std::is_constructible<U1, decltype(nullptr)>::value, "");
     static_assert(!std::is_constructible<U2, decltype(nullptr)>::value, "");
     static_assert(!std::is_constructible<U3, decltype(nullptr)>::value, "");
@@ -81,21 +78,15 @@ void test_sfinae() {
 DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
   { doIncompleteTypeTest(0, nullptr); }
   checkNumIncompleteTypeAlive(0);
-  {
-    doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(0,
-                                                                     nullptr);
-  }
+  { doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(0, nullptr); }
   checkNumIncompleteTypeAlive(0);
   { doIncompleteTypeTest<IncompleteType[]>(0, nullptr); }
   checkNumIncompleteTypeAlive(0);
-  {
-    doIncompleteTypeTest<IncompleteType[], NCDeleter<IncompleteType[]> >(
-        0, nullptr);
-  }
+  { doIncompleteTypeTest<IncompleteType[], NCDeleter<IncompleteType[]> >(0, nullptr); }
   checkNumIncompleteTypeAlive(0);
 })
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_basic<int>();
     test_sfinae<int>();
@@ -105,5 +96,14 @@ int main(int, char**) {
     test_sfinae<int[]>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
index 364dd3aa3adef..cbce5c9c74c5a 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
@@ -37,7 +37,7 @@
 // unique_ptr(pointer) ctor should only require default Deleter ctor
 
 template <bool IsArray>
-void test_pointer() {
+TEST_CONSTEXPR_CXX23 void test_pointer() {
   typedef typename std::conditional<!IsArray, A, A[]>::type ValueT;
   const int expect_alive = IsArray ? 5 : 1;
 #if TEST_STD_VER >= 11
@@ -56,49 +56,66 @@ void test_pointer() {
 #endif
   {
     A* p = newValue<ValueT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
+
     std::unique_ptr<ValueT> s(p);
     assert(s.get() == p);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     A* p = newValue<ValueT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
+
     std::unique_ptr<ValueT, NCDeleter<ValueT> > s(p);
     assert(s.get() == p);
     assert(s.get_deleter().state() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     A* p = newValue<ValueT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
+
     std::unique_ptr<ValueT, DefaultCtorDeleter<ValueT> > s(p);
     assert(s.get() == p);
     assert(s.get_deleter().state() == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
-void test_derived() {
+TEST_CONSTEXPR_CXX23 void test_derived() {
   {
     B* p = new B;
-    assert(A::count == 1);
-    assert(B::count == 1);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 1);
+    }
     std::unique_ptr<A> s(p);
     assert(s.get() == p);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
   {
     B* p = new B;
-    assert(A::count == 1);
-    assert(B::count == 1);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 1);
+    }
     std::unique_ptr<A, NCDeleter<A> > s(p);
     assert(s.get() == p);
     assert(s.get_deleter().state() == 0);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
 }
 
 #if TEST_STD_VER >= 11
@@ -113,7 +130,7 @@ struct GenericDeleter {
 #endif
 
 template <class T>
-void test_sfinae() {
+void TEST_CONSTEXPR_CXX23 test_sfinae() {
 #if TEST_STD_VER >= 11
   { // the constructor does not participate in overload resolution when
     // the deleter is a pointer type
@@ -133,7 +150,7 @@ void test_sfinae() {
 #endif
 }
 
-static void test_sfinae_runtime() {
+static TEST_CONSTEXPR_CXX23 void test_sfinae_runtime() {
 #if TEST_STD_VER >= 11
   { // the constructor does not participate in overload resolution when
     // a base <-> derived conversion would occur.
@@ -164,7 +181,7 @@ DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
   checkNumIncompleteTypeAlive(0);
 })
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_pointer</*IsArray*/ false>();
     test_derived();
@@ -176,5 +193,14 @@ int main(int, char**) {
     test_sfinae_runtime();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
index 59861effb4eff..a91abc856fb19 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
@@ -34,25 +34,25 @@ void my_free(void*) { my_free_called = true; }
 
 #if TEST_STD_VER >= 11
 struct DeleterBase {
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 };
 struct CopyOnlyDeleter : DeleterBase {
-  CopyOnlyDeleter() = default;
-  CopyOnlyDeleter(CopyOnlyDeleter const&) = default;
+  TEST_CONSTEXPR_CXX23 CopyOnlyDeleter()                       = default;
+  TEST_CONSTEXPR_CXX23 CopyOnlyDeleter(CopyOnlyDeleter const&) = default;
   CopyOnlyDeleter(CopyOnlyDeleter&&) = delete;
 };
 struct MoveOnlyDeleter : DeleterBase {
-  MoveOnlyDeleter() = default;
-  MoveOnlyDeleter(MoveOnlyDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 MoveOnlyDeleter()                  = default;
+  TEST_CONSTEXPR_CXX23 MoveOnlyDeleter(MoveOnlyDeleter&&) = default;
 };
 struct NoCopyMoveDeleter : DeleterBase {
-  NoCopyMoveDeleter() = default;
+  TEST_CONSTEXPR_CXX23 NoCopyMoveDeleter()    = default;
   NoCopyMoveDeleter(NoCopyMoveDeleter const&) = delete;
 };
 #endif
 
 template <bool IsArray>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
 #if TEST_STD_VER >= 11
   typedef typename std::conditional<!IsArray, int, int[]>::type VT;
   {
@@ -102,7 +102,7 @@ void test_sfinae() {
 }
 
 template <bool IsArray>
-void test_noexcept() {
+TEST_CONSTEXPR_CXX23 void test_noexcept() {
 #if TEST_STD_VER >= 11
   typedef typename std::conditional<!IsArray, int, int[]>::type VT;
   {
@@ -133,7 +133,7 @@ void test_noexcept() {
 #endif
 }
 
-void test_sfinae_runtime() {
+TEST_CONSTEXPR_CXX23 void test_sfinae_runtime() {
 #if TEST_STD_VER >= 11
   {
     using D = CopyOnlyDeleter;
@@ -204,20 +204,23 @@ void test_sfinae_runtime() {
 }
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<!IsArray, A, A[]>::type VT;
   const int expect_alive = IsArray ? 5 : 1;
   { // MoveConstructible deleter (C-1)
     A* p = newValue<VT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     std::unique_ptr<VT, Deleter<VT> > s(p, Deleter<VT>(5));
     assert(s.get() == p);
     assert(s.get_deleter().state() == 5);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   { // CopyConstructible deleter (C-2)
     A* p = newValue<VT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     CopyDeleter<VT> d(5);
     std::unique_ptr<VT, CopyDeleter<VT> > s(p, d);
     assert(s.get() == p);
@@ -225,10 +228,12 @@ void test_basic() {
     d.set_state(6);
     assert(s.get_deleter().state() == 5);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   { // Reference deleter (C-3)
     A* p = newValue<VT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     NCDeleter<VT> d(5);
     std::unique_ptr<VT, NCDeleter<VT>&> s(p, d);
     assert(s.get() == p);
@@ -237,59 +242,70 @@ void test_basic() {
     d.set_state(6);
     assert(s.get_deleter().state() == 6);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   { // Const Reference deleter (C-4)
     A* p = newValue<VT>(expect_alive);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     NCConstDeleter<VT> d(5);
     std::unique_ptr<VT, NCConstDeleter<VT> const&> s(p, d);
     assert(s.get() == p);
     assert(s.get_deleter().state() == 5);
     assert(&s.get_deleter() == &d);
   }
-  assert(A::count == 0);
-  { // Void and function pointers (C-6,7)
-    typedef typename std::conditional<IsArray, int[], int>::type VT2;
-    my_free_called = false;
-    {
-      int i = 0;
-      std::unique_ptr<VT2, void (*)(void*)> s(&i, my_free);
-      assert(s.get() == &i);
-      assert(s.get_deleter() == my_free);
-      assert(!my_free_called);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    { // Void and function pointers (C-6,7)
+      typedef typename std::conditional<IsArray, int[], int>::type VT2;
+      my_free_called = false;
+      {
+        int i = 0;
+        std::unique_ptr<VT2, void (*)(void*)> s(&i, my_free);
+        assert(s.get() == &i);
+        assert(s.get_deleter() == my_free);
+        assert(!my_free_called);
+      }
+      assert(my_free_called);
     }
-    assert(my_free_called);
   }
 }
 
-void test_basic_single() {
-  assert(A::count == 0);
-  assert(B::count == 0);
+TEST_CONSTEXPR_CXX23 void test_basic_single() {
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+  }
   { // Derived pointers (C-5)
     B* p = new B;
-    assert(A::count == 1);
-    assert(B::count == 1);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 1);
+    }
     std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>(5));
     assert(s.get() == p);
     assert(s.get_deleter().state() == 5);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
-  { // Void and function pointers (C-6,7)
-    my_free_called = false;
-    {
-      int i = 0;
-      std::unique_ptr<void, void (*)(void*)> s(&i, my_free);
-      assert(s.get() == &i);
-      assert(s.get_deleter() == my_free);
-      assert(!my_free_called);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
+
+    { // Void and function pointers (C-6,7)
+      my_free_called = false;
+      {
+        int i = 0;
+        std::unique_ptr<void, void (*)(void*)> s(&i, my_free);
+        assert(s.get() == &i);
+        assert(s.get_deleter() == my_free);
+        assert(!my_free_called);
+      }
+      assert(my_free_called);
     }
-    assert(my_free_called);
   }
 }
 
 template <bool IsArray>
-void test_nullptr() {
+TEST_CONSTEXPR_CXX23 void test_nullptr() {
 #if TEST_STD_VER >= 11
   typedef typename std::conditional<!IsArray, A, A[]>::type VT;
   {
@@ -309,7 +325,7 @@ void test_nullptr() {
 #endif
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_basic</*IsArray*/ false>();
     test_nullptr<false>();
@@ -325,5 +341,14 @@ int main(int, char**) {
     test_noexcept<true>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
index c067f642e6766..54aec49af368e 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
@@ -24,15 +24,15 @@ class Deleter {
   Deleter& operator=(Deleter&);
 
 public:
-  Deleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {}
 
-  int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
 
-  void operator()(void*) { ++state_; }
+  TEST_CONSTEXPR_CXX23 void operator()(void*) { ++state_; }
 };
 
 template <class T>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   Deleter d;
   assert(d.state() == 0);
   {
@@ -43,9 +43,18 @@ void test_basic() {
   assert(d.state() == 0);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic<int>();
   test_basic<int[]>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
index f080165d561ad..7aedac99030cb 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
@@ -19,7 +19,7 @@
 #include "unique_ptr_test_helper.h"
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 3 : 1;
 #if TEST_STD_VER >= 11
@@ -31,10 +31,12 @@ void test_basic() {
 #endif
   {
     std::unique_ptr<VT> p(newValue<VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     A* ap = p.get();
     A* a = p.release();
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(p.get() == nullptr);
     assert(ap == a);
     assert(a != nullptr);
@@ -44,14 +46,25 @@ void test_basic() {
     else
       delete a;
 
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
index 46569918a5f98..275ab3df02caf 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
@@ -19,90 +19,106 @@
 #include "unique_ptr_test_helper.h"
 
 template <bool IsArray>
-void test_reset_pointer() {
+TEST_CONSTEXPR_CXX23 void test_reset_pointer() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 3 : 1;
 #if TEST_STD_VER >= 11
   {
     using U = std::unique_ptr<VT>;
-    U u; ((void)u);
+    U u;
+    ((void)u);
     ASSERT_NOEXCEPT(u.reset((A*)nullptr));
   }
 #endif
   {
     std::unique_ptr<VT> p(newValue<VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     A* i = p.get();
     assert(i != nullptr);
     A* new_value = newValue<VT>(expect_alive);
-    assert(A::count == (expect_alive * 2));
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == (expect_alive * 2));
     p.reset(new_value);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(p.get() == new_value);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
   {
     std::unique_ptr<const VT> p(newValue<const VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     const A* i = p.get();
     assert(i != nullptr);
     A* new_value = newValue<VT>(expect_alive);
-    assert(A::count == (expect_alive * 2));
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == (expect_alive * 2));
     p.reset(new_value);
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     assert(p.get() == new_value);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
 template <bool IsArray>
-void test_reset_nullptr() {
+TEST_CONSTEXPR_CXX23 void test_reset_nullptr() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 3 : 1;
 #if TEST_STD_VER >= 11
   {
     using U = std::unique_ptr<VT>;
-    U u; ((void)u);
+    U u;
+    ((void)u);
     ASSERT_NOEXCEPT(u.reset(nullptr));
   }
 #endif
   {
     std::unique_ptr<VT> p(newValue<VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     A* i = p.get();
     assert(i != nullptr);
     p.reset(nullptr);
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
     assert(p.get() == nullptr);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
-
 template <bool IsArray>
-void test_reset_no_arg() {
+TEST_CONSTEXPR_CXX23 void test_reset_no_arg() {
   typedef typename std::conditional<IsArray, A[], A>::type VT;
   const int expect_alive = IsArray ? 3 : 1;
 #if TEST_STD_VER >= 11
   {
     using U = std::unique_ptr<VT>;
-    U u; ((void)u);
+    U u;
+    ((void)u);
     ASSERT_NOEXCEPT(u.reset());
   }
 #endif
   {
     std::unique_ptr<VT> p(newValue<VT>(expect_alive));
-    assert(A::count == expect_alive);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == expect_alive);
     A* i = p.get();
     assert(i != nullptr);
     p.reset();
-    assert(A::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 0);
     assert(p.get() == nullptr);
   }
-  assert(A::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 0);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     test_reset_pointer</*IsArray*/ false>();
     test_reset_nullptr<false>();
@@ -114,5 +130,14 @@ int main(int, char**) {
     test_reset_no_arg<true>();
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
index 583cbcf50c1be..d5e5c545f313b 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
@@ -18,31 +18,52 @@
 #include "test_macros.h"
 #include "unique_ptr_test_helper.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   {
     std::unique_ptr<A> p(new A);
-    assert(A::count == 1);
-    assert(B::count == 0);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 0);
+    }
     A* i = p.get();
     assert(i != nullptr);
     p.reset(new B);
-    assert(A::count == 1);
-    assert(B::count == 1);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 1);
+    }
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
   {
     std::unique_ptr<A> p(new B);
-    assert(A::count == 1);
-    assert(B::count == 1);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 1);
+    }
     A* i = p.get();
     assert(i != nullptr);
     p.reset(new B);
-    assert(A::count == 1);
-    assert(B::count == 1);
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert(A::count == 1);
+      assert(B::count == 1);
+    }
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(A::count == 0);
+    assert(B::count == 0);
   }
-  assert(A::count == 0);
-  assert(B::count == 0);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
index 5285bca163734..8eeca6f5ce98c 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
@@ -19,10 +19,21 @@
 struct A {
   std::unique_ptr<A> ptr_;
 
-  A() : ptr_(this) {}
-  void reset() { ptr_.reset(); }
+  TEST_CONSTEXPR_CXX23 A() : ptr_(this) {}
+  TEST_CONSTEXPR_CXX23 void reset() { ptr_.reset(); }
 };
 
-int main(int, char**) { (new A)->reset();
+TEST_CONSTEXPR_CXX23 bool test() {
+  (new A)->reset();
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
index 35e997e30659f..41391b49fc5d2 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
@@ -21,25 +21,34 @@
 struct TT {
   int state_;
   static int count;
-  TT() : state_(-1) { ++count; }
-  explicit TT(int i) : state_(i) { ++count; }
-  TT(const TT& a) : state_(a.state_) { ++count; }
-  TT& operator=(const TT& a) {
+  TEST_CONSTEXPR_CXX23 TT() : state_(-1) {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 explicit TT(int i) : state_(i) {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 TT(const TT& a) : state_(a.state_) {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 TT& operator=(const TT& a) {
     state_ = a.state_;
     return *this;
   }
-  ~TT() { --count; }
-
-  friend bool operator==(const TT& x, const TT& y) {
-    return x.state_ == y.state_;
+  TEST_CONSTEXPR_CXX23 ~TT() {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      --count;
   }
+
+  friend TEST_CONSTEXPR_CXX23 bool operator==(const TT& x, const TT& y) { return x.state_ == y.state_; }
 };
 
 int TT::count = 0;
 
 template <class T>
-typename std::remove_all_extents<T>::type* newValueInit(int size,
-                                                        int new_value) {
+TEST_CONSTEXPR_CXX23 typename std::remove_all_extents<T>::type* newValueInit(int size, int new_value) {
   typedef typename std::remove_all_extents<T>::type VT;
   VT* p = newValue<T>(size);
   for (int i = 0; i < size; ++i)
@@ -48,7 +57,7 @@ typename std::remove_all_extents<T>::type* newValueInit(int size,
 }
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, TT[], TT>::type VT;
   const int expect_alive = IsArray ? 5 : 1;
 #if TEST_STD_VER >= 11
@@ -76,14 +85,25 @@ void test_basic() {
     assert(s2.get() == p1);
     assert(*s2.get() == TT(1));
     assert(s2.get_deleter().state() == 1);
-    assert(TT::count == (expect_alive * 2));
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(TT::count == (expect_alive * 2));
   }
-  assert(TT::count == 0);
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(TT::count == 0);
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
index fae3576b1252d..4a1e9704afc9c 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
@@ -17,9 +17,18 @@
 
 #include "test_macros.h"
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   std::unique_ptr<int> p(new int(3));
   assert(*p == 3);
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
index 500821fb8175b..cc68297c3ea2e 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
@@ -10,7 +10,7 @@
 
 // unique_ptr
 
-// test op*()
+// test constexpr explicit operator bool() const noexcept; // constexpr since C++23
 
 #include <memory>
 #include <cassert>
@@ -19,7 +19,7 @@
 #include "unique_ptr_test_helper.h"
 
 template <class UPtr>
-void doTest(UPtr& p, bool ExpectTrue) {
+TEST_CONSTEXPR_CXX23 void doTest(UPtr& p, bool ExpectTrue) {
   if (p)
     assert(ExpectTrue);
   else
@@ -32,7 +32,7 @@ void doTest(UPtr& p, bool ExpectTrue) {
 }
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, int[], int>::type VT;
   typedef std::unique_ptr<VT> U;
   {
@@ -59,9 +59,18 @@ void test_basic() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
-  return 0;
+  return true;
 }
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
+  return 0;
+}
\ No newline at end of file

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
index 1ff965f563e12..3bd3788960e2a 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
@@ -19,7 +19,7 @@
 #include "unique_ptr_test_helper.h"
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, int[], int>::type VT;
   typedef const VT CVT;
   {
@@ -44,9 +44,18 @@ void test_basic() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
index e440a95991c72..fc34d17b6fdb2 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
@@ -17,16 +17,16 @@
 #include "test_macros.h"
 
 struct Deleter {
-  Deleter() {}
+  TEST_CONSTEXPR_CXX23 Deleter() {}
 
-  void operator()(void*) const {}
+  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
 
-  int test() { return 5; }
-  int test() const { return 6; }
+  TEST_CONSTEXPR_CXX23 int test() { return 5; }
+  TEST_CONSTEXPR_CXX23 int test() const { return 6; }
 };
 
 template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
   typedef typename std::conditional<IsArray, int[], int>::type VT;
   {
     std::unique_ptr<int, Deleter> p;
@@ -58,9 +58,18 @@ void test_basic() {
   }
 }
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   test_basic</*IsArray*/ false>();
   test_basic<true>();
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
index 4a50d1f29d17a..7d247b8715beb 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
@@ -20,12 +20,21 @@
 struct A {
   int i_;
 
-  A() : i_(7) {}
+  TEST_CONSTEXPR_CXX23 A() : i_(7) {}
 };
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   std::unique_ptr<A> p(new A);
   assert(p->i_ == 7);
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
index 1b11d695e96b5..18dfbcc0f9be9 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
@@ -22,12 +22,16 @@ class A {
   static int next_;
 
 public:
-  A() : state_(++next_) {}
-  int get() const { return state_; }
+  TEST_CONSTEXPR_CXX23 A() : state_(0) {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      state_ = ++next_;
+  }
+
+  TEST_CONSTEXPR_CXX23 int get() const { return state_; }
 
-  friend bool operator==(const A& x, int y) { return x.state_ == y; }
+  friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, int y) { return x.state_ == y; }
 
-  A& operator=(int i) {
+  TEST_CONSTEXPR_CXX23 A& operator=(int i) {
     state_ = i;
     return *this;
   }
@@ -35,11 +39,13 @@ class A {
 
 int A::next_ = 0;
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   std::unique_ptr<A[]> p(new A[3]);
-  assert(p[0] == 1);
-  assert(p[1] == 2);
-  assert(p[2] == 3);
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(p[0] == 1);
+    assert(p[1] == 2);
+    assert(p[2] == 3);
+  }
   p[0] = 3;
   p[1] = 2;
   p[2] = 1;
@@ -47,5 +53,14 @@ int main(int, char**) {
   assert(p[1] == 2);
   assert(p[2] == 1);
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
index f3d9fb68f9674..7aef0eb568887 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
@@ -17,31 +17,40 @@
 
 class foo {
 public:
-    foo () : val_(3) {}
-    int get () const { return val_; }
+  TEST_CONSTEXPR_CXX23 foo() : val_(3) {}
+  TEST_CONSTEXPR_CXX23 int get() const { return val_; }
+
 private:
-    int val_;
-    };
+  int val_;
+};
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX23 bool test() {
+  {
     auto p1 = std::make_unique<int[]>(5);
-    for ( int i = 0; i < 5; ++i )
-        assert ( p1[i] == 0 );
-    }
+    for (int i = 0; i < 5; ++i)
+      assert(p1[i] == 0);
+  }
 
-    {
+  {
     auto p2 = std::make_unique<std::string[]>(5);
-    for ( int i = 0; i < 5; ++i )
-        assert ( p2[i].size () == 0 );
-    }
+    for (int i = 0; i < 5; ++i)
+      assert(p2[i].size() == 0);
+  }
 
-    {
+  {
     auto p3 = std::make_unique<foo[]>(7);
-    for ( int i = 0; i < 7; ++i )
-        assert ( p3[i].get () == 3 );
-    }
+    for (int i = 0; i < 7; ++i)
+      assert(p3[i].get() == 3);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
index 08b72289ddb37..b9211f300ea5d 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
@@ -13,23 +13,31 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX23 bool test() {
+  {
     std::unique_ptr<int> p1 = std::make_unique<int>(1);
-    assert ( *p1 == 1 );
-    p1 = std::make_unique<int> ();
-    assert ( *p1 == 0 );
-    }
+    assert(*p1 == 1);
+    p1 = std::make_unique<int>();
+    assert(*p1 == 0);
+  }
 
-    {
-    std::unique_ptr<std::string> p2 = std::make_unique<std::string> ( "Meow!" );
-    assert ( *p2 == "Meow!" );
-    p2 = std::make_unique<std::string> ();
-    assert ( *p2 == "" );
-    p2 = std::make_unique<std::string> ( 6, 'z' );
-    assert ( *p2 == "zzzzzz" );
-    }
+  {
+    std::unique_ptr<std::string> p2 = std::make_unique<std::string>("Meow!");
+    assert(*p2 == "Meow!");
+    p2 = std::make_unique<std::string>();
+    assert(*p2 == "");
+    p2 = std::make_unique<std::string>(6, 'z');
+    assert(*p2 == "zzzzzz");
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp
index 85ad5316e7338..5779ba30e7c88 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp
@@ -41,5 +41,6 @@ int main(int, char**)
     assert(p != nullptr);
   }
 #endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
index d4c00f46748f9..8dafb72a61993 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
@@ -10,42 +10,38 @@
 
 // default_delete
 
+// convert constructor
+
 #include <memory>
 #include <cassert>
 
 #include "test_macros.h"
+#include "unique_ptr_test_helper.h"
 
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
-    : public A
-{
-    static int count;
-    B() {++count;}
-    B(const B& other) : A(other) {++count;}
-    virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main(int, char**)
-{
-    std::default_delete<B> d2;
-    std::default_delete<A> d1 = d2;
-    A* p = new B;
+TEST_CONSTEXPR_CXX23 bool test() {
+  std::default_delete<B> d2;
+  std::default_delete<A> d1 = d2;
+  A* p                      = new B;
+  if (!TEST_IS_CONSTANT_EVALUATED) {
     assert(A::count == 1);
     assert(B::count == 1);
-    d1(p);
+  }
+
+  d1(p);
+
+  if (!TEST_IS_CONSTANT_EVALUATED) {
     assert(A::count == 0);
     assert(B::count == 0);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
index a5101b9889dc6..3ac3e4fc0f370 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
@@ -14,24 +14,27 @@
 #include <cassert>
 
 #include "test_macros.h"
+#include "unique_ptr_test_helper.h"
 
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
-};
+TEST_CONSTEXPR_CXX23 bool test() {
+  std::default_delete<A> d;
+  A* p = new A;
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 1);
 
-int A::count = 0;
+  d(p);
 
-int main(int, char**)
-{
-    std::default_delete<A> d;
-    A* p = new A;
-    assert(A::count == 1);
-    d(p);
+  if (!TEST_IS_CONSTANT_EVALUATED)
     assert(A::count == 0);
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
index 0eae429fd4098..f95e2d7c794a9 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
@@ -11,7 +11,7 @@
 // default_delete[]
 
 // template <class U>
-//   default_delete(const default_delete<U[]>&);
+//   constexpr default_delete(const default_delete<U[]>&); // constexpr since C++23
 //
 // This constructor shall not participate in overload resolution unless
 //   U(*)[] is convertible to T(*)[].
@@ -21,11 +21,19 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    std::default_delete<int[]> d1;
-    std::default_delete<const int[]> d2 = d1;
-    ((void)d2);
+TEST_CONSTEXPR_CXX23 bool test() {
+  std::default_delete<int[]> d1;
+  std::default_delete<const int[]> d2 = d1;
+  ((void)d2);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
index 1693d11418d8b..af4d2eebf83f2 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
@@ -16,24 +16,27 @@
 #include <cassert>
 
 #include "test_macros.h"
+#include "unique_ptr_test_helper.h"
 
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    ~A() {--count;}
-};
+TEST_CONSTEXPR_CXX23 bool test() {
+  std::default_delete<A[]> d;
+  A* p = new A[3];
+  if (!TEST_IS_CONSTANT_EVALUATED)
+    assert(A::count == 3);
 
-int A::count = 0;
+  d(p);
 
-int main(int, char**)
-{
-    std::default_delete<A[]> d;
-    A* p = new A[3];
-    assert(A::count == 3);
-    d(p);
+  if (!TEST_IS_CONSTANT_EVALUATED)
     assert(A::count == 0);
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp
new file mode 100644
index 0000000000000..f9845769d0767
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Includes Microsoft's test that tests the entire header.
+
+#include "test.cpp"

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp
new file mode 100644
index 0000000000000..8a80122a67e3d
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp
@@ -0,0 +1,128 @@
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include <cassert>
+#include <memory>
+#include <utility>
+
+#include "test_macros.h"
+
+using namespace std;
+
+struct Dummy {
+  constexpr int test() const { return 10; }
+};
+
+constexpr bool test() {
+  // [memory.syn]
+  {
+    // FIXME no make_unique_for_overwrite support
+    //auto p1 = make_unique<int>(42);
+    //auto p2 = make_unique_for_overwrite<int>();
+    //swap(p1, p2);
+    //assert(p1 == p1);
+    //assert(p1 != p2);
+
+    //auto p3 = make_unique<int[]>(10);
+    //auto p4 = make_unique_for_overwrite<int[]>(4);
+    //swap(p3, p4);
+    //assert(p3 == p3);
+    //assert(p3 != p4);
+
+    auto p5 = unique_ptr<int>{nullptr};
+    assert(p5 == nullptr);
+    assert(nullptr == p5);
+    assert(!(p5 != nullptr));
+    assert(!(nullptr != p5));
+    assert(!(p5 < nullptr));
+    assert(!(nullptr < p5));
+    assert(p5 <= nullptr);
+    assert(nullptr <= p5);
+    assert(!(p5 > nullptr));
+    assert(!(nullptr > p5));
+    assert(p5 >= nullptr);
+    assert(nullptr >= p5);
+    assert((p5 <=> nullptr) == strong_ordering::equal);
+    assert((nullptr <=> p5) == strong_ordering::equal);
+  }
+
+  // changes in [unique.ptr.dltr.dflt] and [unique.ptr.dltr.dflt1]
+  // will be tested via destructors and copy assign/constructors
+
+  // [unique.ptr.single.general]
+  {
+    // constructors
+    auto p1 = unique_ptr<int>{new int{}};
+    auto d1 = default_delete<int>{};
+    auto p2 = unique_ptr<int>{new int{}, d1};
+    auto p3 = unique_ptr<int>{new int{}, default_delete<int>{}};
+    auto p4 = std::move(p3);
+    auto p5 = unique_ptr<int>{nullptr};
+    auto p6 = unique_ptr<int, default_delete<int>&>{new int{}, d1};
+    auto p7 = unique_ptr<int>{std::move(p6)};
+
+    // assignment
+    p3      = std::move(p4);
+    auto p8 = unique_ptr<int, default_delete<int>&>{new int{}, d1};
+    p7      = std::move(p8);
+    p1      = nullptr;
+
+    // observers
+    assert(*p2 == 0);
+    auto p9 = unique_ptr<Dummy>{new Dummy};
+    assert(p9->test() == 10);
+    assert(p2.get() != nullptr);
+    [[maybe_unused]] auto& d2 = p2.get_deleter();
+    [[maybe_unused]] auto& d3 = as_const(p2).get_deleter();
+    auto b1                   = static_cast<bool>(p2);
+    assert(b1);
+
+    // modifiers
+    p1.reset();
+    p1.reset(new int{});
+    auto manual_delete = p2.release();
+    delete manual_delete;
+    p5.swap(p1);
+  }
+
+  // [unique.ptr.runtime.general]
+  {
+    // constructors
+    auto p1 = unique_ptr<int[]>{new int[5]};
+    auto d1 = default_delete<int[]>{};
+    auto p2 = unique_ptr<int[]>{new int[5], d1};
+    auto p3 = unique_ptr<int[]>{new int[5], default_delete<int[]>{}};
+    auto p4 = std::move(p1);
+    auto p5 = unique_ptr<int[], default_delete<int[]>&>{new int[5], d1};
+    auto p6 = unique_ptr<int[]>{std::move(p5)};
+
+    // assignment
+    p1      = std::move(p4);
+    auto p7 = unique_ptr<int[], default_delete<int[]>&>{new int[5], d1};
+    p6      = std::move(p7);
+    p4      = nullptr;
+
+    // observers
+    p1[0] = 50;
+    assert(p1[0] == 50);
+    assert(p1.get() != nullptr);
+    [[maybe_unused]] auto& d2 = p1.get_deleter();
+    [[maybe_unused]] auto& d3 = as_const(p1).get_deleter();
+    auto b1                   = static_cast<bool>(p1);
+    assert(b1);
+
+    // modifiers
+    auto manual_delete = p1.release();
+    delete[] manual_delete;
+    p1.reset(new int[3]);
+    p1.reset(nullptr);
+    p1.reset();
+    p1.swap(p4);
+  }
+
+  return true;
+}
+
+static_assert(test());
+
+int main() {} // COMPILE-ONLY

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
index 68f69ea99b1cc..38e289bddcb71 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
@@ -47,26 +47,9 @@
 #include "test_macros.h"
 #include "deleter_types.h"
 #include "test_comparisons.h"
+#include "unique_ptr_test_helper.h"
 
-struct A {
-  static int count;
-  A() { ++count; }
-  A(const A&) { ++count; }
-  virtual ~A() { --count; }
-};
-
-int A::count = 0;
-
-struct B : public A {
-  static int count;
-  B() { ++count; }
-  B(const B& other) : A(other) { ++count; }
-  virtual ~B() { --count; }
-};
-
-int B::count = 0;
-
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
   AssertComparisonsReturnBool<std::unique_ptr<int> >();
 #if TEST_STD_VER > 17
   AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>>();
@@ -81,14 +64,16 @@ int main(int, char**) {
 
     assert(!(p1 == p2));
     assert(p1 != p2);
-    assert((p1 < p2) == (ptr1 < ptr2));
-    assert((p1 <= p2) == (ptr1 <= ptr2));
-    assert((p1 > p2) == (ptr1 > ptr2));
-    assert((p1 >= p2) == (ptr1 >= ptr2));
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert((p1 < p2) == (ptr1 < ptr2));
+      assert((p1 <= p2) == (ptr1 <= ptr2));
+      assert((p1 > p2) == (ptr1 > ptr2));
+      assert((p1 >= p2) == (ptr1 >= ptr2));
 #if TEST_STD_VER > 17
-    assert((p1 <=> p2) != std::strong_ordering::equal);
-    assert((p1 <=> p2) == (ptr1 <=> ptr2));
+      assert((p1 <=> p2) != std::strong_ordering::equal);
+      assert((p1 <=> p2) == (ptr1 <=> ptr2));
 #endif
+    }
   }
   // Pointers of 
diff erent type
   {
@@ -98,14 +83,16 @@ int main(int, char**) {
     const std::unique_ptr<B, Deleter<B> > p2(ptr2);
     assert(!(p1 == p2));
     assert(p1 != p2);
-    assert((p1 < p2) == (ptr1 < ptr2));
-    assert((p1 <= p2) == (ptr1 <= ptr2));
-    assert((p1 > p2) == (ptr1 > ptr2));
-    assert((p1 >= p2) == (ptr1 >= ptr2));
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert((p1 < p2) == (ptr1 < ptr2));
+      assert((p1 <= p2) == (ptr1 <= ptr2));
+      assert((p1 > p2) == (ptr1 > ptr2));
+      assert((p1 >= p2) == (ptr1 >= ptr2));
 #if TEST_STD_VER > 17
     assert((p1 <=> p2) != std::strong_ordering::equal);
     assert((p1 <=> p2) == (ptr1 <=> ptr2));
 #endif
+    }
   }
   // Pointers of same array type
   {
@@ -115,14 +102,16 @@ int main(int, char**) {
     const std::unique_ptr<A[], Deleter<A[]> > p2(ptr2);
     assert(!(p1 == p2));
     assert(p1 != p2);
-    assert((p1 < p2) == (ptr1 < ptr2));
-    assert((p1 <= p2) == (ptr1 <= ptr2));
-    assert((p1 > p2) == (ptr1 > ptr2));
-    assert((p1 >= p2) == (ptr1 >= ptr2));
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert((p1 < p2) == (ptr1 < ptr2));
+      assert((p1 <= p2) == (ptr1 <= ptr2));
+      assert((p1 > p2) == (ptr1 > ptr2));
+      assert((p1 >= p2) == (ptr1 >= ptr2));
 #if TEST_STD_VER > 17
     assert((p1 <=> p2) != std::strong_ordering::equal);
     assert((p1 <=> p2) == (ptr1 <=> ptr2));
 #endif
+    }
   }
   // Pointers of 
diff erent array types
   {
@@ -132,14 +121,16 @@ int main(int, char**) {
     const std::unique_ptr<B[], Deleter<B[]> > p2(ptr2);
     assert(!(p1 == p2));
     assert(p1 != p2);
-    assert((p1 < p2) == (ptr1 < ptr2));
-    assert((p1 <= p2) == (ptr1 <= ptr2));
-    assert((p1 > p2) == (ptr1 > ptr2));
-    assert((p1 >= p2) == (ptr1 >= ptr2));
+    if (!TEST_IS_CONSTANT_EVALUATED) {
+      assert((p1 < p2) == (ptr1 < ptr2));
+      assert((p1 <= p2) == (ptr1 <= ptr2));
+      assert((p1 > p2) == (ptr1 > ptr2));
+      assert((p1 >= p2) == (ptr1 >= ptr2));
 #if TEST_STD_VER > 17
     assert((p1 <=> p2) != std::strong_ordering::equal);
     assert((p1 <=> p2) == (ptr1 <=> ptr2));
 #endif
+    }
   }
   // Default-constructed pointers of same type
   {
@@ -147,7 +138,8 @@ int main(int, char**) {
     const std::unique_ptr<A, Deleter<A> > p2;
     assert(p1 == p2);
 #if TEST_STD_VER > 17
-    assert((p1 <=> p2) == std::strong_ordering::equal);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert((p1 <=> p2) == std::strong_ordering::equal);
 #endif
   }
   // Default-constructed pointers of 
diff erent type
@@ -156,9 +148,19 @@ int main(int, char**) {
     const std::unique_ptr<B, Deleter<B> > p2;
     assert(p1 == p2);
 #if TEST_STD_VER > 17
-    assert((p1 <=> p2) == std::strong_ordering::equal);
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert((p1 <=> p2) == std::strong_ordering::equal);
 #endif
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
index c3ab43d4509fb..ddd02a455c588 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
@@ -8,69 +8,74 @@
 
 // <memory>
 
-// shared_ptr
+// unique_ptr
 
 // template <class T, class D>
-//     bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+//     constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // constexpr since C++23
 // template <class T, class D>
-//     bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+//     bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;           // removed in C++20
 // template <class T, class D>
-//     bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+//     bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;           // removed in C++20
 // template <class T, class D>
-//     bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+//     bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;           // removed in C++20
 // template <class T, class D>
-//     bool operator<(const unique_ptr<T, D>& x, nullptr_t);
+//     constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);           // constexpr since C++23
 // template <class T, class D>
-//     bool operator<(nullptr_t, const unique_ptr<T, D>& y);
+//     constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y);           // constexpr since C++23
 // template <class T, class D>
-//     bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
+//     constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);          // constexpr since C++23
 // template <class T, class D>
-//     bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
+//     constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y);          // constexpr since C++23
 // template <class T, class D>
-//     bool operator>(const unique_ptr<T, D>& x, nullptr_t);
+//     constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);           // constexpr since C++23
 // template <class T, class D>
-//     bool operator>(nullptr_t, const unique_ptr<T, D>& y);
+//     constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y);           // constexpr since C++23
 // template <class T, class D>
-//     bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
+//     constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);          // constexpr since C++23
 // template <class T, class D>
-//     bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
+//     constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y);          // constexpr since C++23
 // template<class T, class D>
 //   requires three_way_comparable<typename unique_ptr<T, D>::pointer>
 //   constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
-//     operator<=>(const unique_ptr<T, D>& x, nullptr_t);                            // C++20
+//     operator<=>(const unique_ptr<T, D>& x, nullptr_t);                        // C++20
 
 #include <memory>
 #include <cassert>
+#include <type_traits>
 
 #include "test_macros.h"
 #include "test_comparisons.h"
 
-int main(int, char**)
-{
-  AssertEqualityAreNoexcept<std::unique_ptr<int>, nullptr_t>();
-  AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >();
-  AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>();
-  AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >();
+TEST_CONSTEXPR_CXX23 bool test() {
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    AssertEqualityAreNoexcept<std::unique_ptr<int>, nullptr_t>();
+    AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >();
+    AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>();
+    AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >();
 #if TEST_STD_VER > 17
-  AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>();
-  AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>();
+    AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>();
+    AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>();
 #endif
+  }
 
   const std::unique_ptr<int> p1(new int(1));
   assert(!(p1 == nullptr));
   assert(!(nullptr == p1));
-  assert(!(p1 < nullptr));
-  assert((nullptr < p1));
-  assert(!(p1 <= nullptr));
-  assert((nullptr <= p1));
-  assert((p1 > nullptr));
-  assert(!(nullptr > p1));
-  assert((p1 >= nullptr));
-  assert(!(nullptr >= p1));
+  // A pointer to allocated storage and a nullptr can't be compared at compile-time
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    assert(!(p1 < nullptr));
+    assert((nullptr < p1));
+    assert(!(p1 <= nullptr));
+    assert((nullptr <= p1));
+    assert((p1 > nullptr));
+    assert(!(nullptr > p1));
+    assert((p1 >= nullptr));
+    assert(!(nullptr >= p1));
 #if TEST_STD_VER > 17
-  assert((nullptr <=> p1) == std::strong_ordering::less);
-  assert((p1 <=> nullptr) == std::strong_ordering::greater);
+    assert((nullptr <=> p1) == std::strong_ordering::less);
+    assert((p1 <=> nullptr) == std::strong_ordering::greater);
 #endif
+  }
 
   const std::unique_ptr<int> p2;
   assert((p2 == nullptr));
@@ -87,5 +92,14 @@ int main(int, char**)
   assert((nullptr <=> p2) == std::strong_ordering::equivalent);
 #endif
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
index 4e45bbaef355e..c47883acab06e 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
@@ -22,31 +22,45 @@ struct A
 {
     int state_;
     static int count;
-    A() : state_(0) {++count;}
-    explicit A(int i) : state_(i) {++count;}
-    A(const A& a) : state_(a.state_) {++count;}
-    A& operator=(const A& a) {state_ = a.state_; return *this;}
-    ~A() {--count;}
+    TEST_CONSTEXPR_CXX23 A() : state_(0) {
+      if (!TEST_IS_CONSTANT_EVALUATED)
+        ++count;
+    }
+    TEST_CONSTEXPR_CXX23 explicit A(int i) : state_(i) {
+      if (!TEST_IS_CONSTANT_EVALUATED)
+        ++count;
+    }
+    TEST_CONSTEXPR_CXX23 A(const A& a) : state_(a.state_) {
+      if (!TEST_IS_CONSTANT_EVALUATED)
+        ++count;
+    }
+    TEST_CONSTEXPR_CXX23 A& operator=(const A& a) {
+      state_ = a.state_;
+      return *this;
+    }
+    TEST_CONSTEXPR_CXX23 ~A() {
+      if (!TEST_IS_CONSTANT_EVALUATED)
+        --count;
+    }
 
-    friend bool operator==(const A& x, const A& y)
-        {return x.state_ == y.state_;}
+    friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
 };
 
 int A::count = 0;
 
 template <class T>
 struct NonSwappableDeleter {
-  explicit NonSwappableDeleter(int) {}
-  NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
-  void operator()(T*) const {}
+  TEST_CONSTEXPR_CXX23 explicit NonSwappableDeleter(int) {}
+  TEST_CONSTEXPR_CXX23 NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
+  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}
+
 private:
   NonSwappableDeleter(NonSwappableDeleter const&);
 
 };
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX23 bool test() {
+  {
     A* p1 = new A(1);
     std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));
     A* p2 = new A(2);
@@ -64,10 +78,12 @@ int main(int, char**)
     assert(s2.get() == p1);
     assert(*s2 == A(1));
     assert(s2.get_deleter().state() == 1);
-    assert(A::count == 2);
-    }
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 2);
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED)
     assert(A::count == 0);
-    {
+  {
     A* p1 = new A[3];
     std::unique_ptr<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(1));
     A* p2 = new A[3];
@@ -81,8 +97,10 @@ int main(int, char**)
     assert(s1.get_deleter().state() == 2);
     assert(s2.get() == p1);
     assert(s2.get_deleter().state() == 1);
-    assert(A::count == 6);
-    }
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      assert(A::count == 6);
+  }
+  if (!TEST_IS_CONSTANT_EVALUATED)
     assert(A::count == 0);
 #if TEST_STD_VER >= 11
     {
@@ -99,5 +117,14 @@ int main(int, char**)
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER >= 23
+  static_assert(test());
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/support/deleter_types.h b/libcxx/test/support/deleter_types.h
index f8aafc12bfdaa..c5680020b0646 100644
--- a/libcxx/test/support/deleter_types.h
+++ b/libcxx/test/support/deleter_types.h
@@ -25,441 +25,440 @@
 #if TEST_STD_VER >= 11
 
 template <class T>
-class Deleter
-{
-    int state_;
+class Deleter {
+  int state_;
 
-    Deleter(const Deleter&);
-    Deleter& operator=(const Deleter&);
+  Deleter(const Deleter&);
+  Deleter& operator=(const Deleter&);
 
 public:
-    Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
-    Deleter& operator=(Deleter&& r)
-    {
-        state_ = r.state_;
-        r.state_ = 0;
-        return *this;
-    }
-
-
-    Deleter() : state_(0) {}
-    explicit Deleter(int s) : state_(s) {}
-    ~Deleter() {assert(state_ >= 0); state_ = -1;}
-
-    template <class U>
-        Deleter(Deleter<U>&& d,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
-            : state_(d.state()) {d.set_state(0);}
+  TEST_CONSTEXPR_CXX23 Deleter(Deleter&& r) : state_(r.state_) { r.state_ = 0; }
+  TEST_CONSTEXPR_CXX23 Deleter& operator=(Deleter&& r) {
+    state_   = r.state_;
+    r.state_ = 0;
+    return *this;
+  }
+
+  TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit Deleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~Deleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
+
+  template <class U>
+  TEST_CONSTEXPR_CXX23 Deleter(Deleter<U>&& d, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
+      : state_(d.state()) {
+    d.set_state(0);
+  }
 
 private:
-    template <class U>
-        Deleter(const Deleter<U>& d,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
+  template <class U>
+  Deleter(const Deleter<U>& d, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
+
 public:
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) {delete p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; }
 };
 
 template <class T>
-class Deleter<T[]>
-{
-    int state_;
+class Deleter<T[]> {
+  int state_;
 
-    Deleter(const Deleter&);
-    Deleter& operator=(const Deleter&);
+  Deleter(const Deleter&);
+  Deleter& operator=(const Deleter&);
 
 public:
-
-    Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
-    Deleter& operator=(Deleter&& r)
-    {
-        state_ = r.state_;
-        r.state_ = 0;
-        return *this;
-    }
-
-    Deleter() : state_(0) {}
-    explicit Deleter(int s) : state_(s) {}
-    ~Deleter() {assert(state_ >= 0); state_ = -1;}
-
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
-
-    void operator()(T* p) {delete [] p;}
+  TEST_CONSTEXPR_CXX23 Deleter(Deleter&& r) : state_(r.state_) { r.state_ = 0; }
+  TEST_CONSTEXPR_CXX23 Deleter& operator=(Deleter&& r) {
+    state_   = r.state_;
+    r.state_ = 0;
+    return *this;
+  }
+
+  TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit Deleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~Deleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
+
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
+
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; }
 };
 
 #else // TEST_STD_VER < 11
 
 template <class T>
-class Deleter
-{
-    mutable int state_;
+class Deleter {
+  mutable int state_;
 
 public:
-    Deleter() : state_(0) {}
-    explicit Deleter(int s) : state_(s) {}
+  Deleter() : state_(0) {}
+  explicit Deleter(int s) : state_(s) {}
 
-    Deleter(Deleter const & other) : state_(other.state_) {
-        other.state_ = 0;
-    }
-    Deleter& operator=(Deleter const& other) {
-        state_ = other.state_;
-        other.state_ = 0;
-        return *this;
-    }
+  Deleter(Deleter const& other) : state_(other.state_) { other.state_ = 0; }
+  Deleter& operator=(Deleter const& other) {
+    state_       = other.state_;
+    other.state_ = 0;
+    return *this;
+  }
 
-    ~Deleter() {assert(state_ >= 0); state_ = -1;}
+  ~Deleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    template <class U>
-        Deleter(Deleter<U> d,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
-            : state_(d.state()) {}
+  template <class U>
+  Deleter(Deleter<U> d, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) : state_(d.state()) {}
 
 public:
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  int state() const { return state_; }
+  void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) {delete p;}
+  void operator()(T* p) { delete p; }
 };
 
 template <class T>
-class Deleter<T[]>
-{
-    mutable int state_;
+class Deleter<T[]> {
+  mutable int state_;
 
 public:
-
-    Deleter(Deleter const& other) : state_(other.state_) {
-        other.state_ = 0;
-    }
-    Deleter& operator=(Deleter const& other) {
-        state_ = other.state_;
-        other.state_ = 0;
-        return *this;
-    }
-
-    Deleter() : state_(0) {}
-    explicit Deleter(int s) : state_(s) {}
-    ~Deleter() {assert(state_ >= 0); state_ = -1;}
-
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
-
-    void operator()(T* p) {delete [] p;}
+  Deleter(Deleter const& other) : state_(other.state_) { other.state_ = 0; }
+  Deleter& operator=(Deleter const& other) {
+    state_       = other.state_;
+    other.state_ = 0;
+    return *this;
+  }
+
+  Deleter() : state_(0) {}
+  explicit Deleter(int s) : state_(s) {}
+  ~Deleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
+
+  int state() const { return state_; }
+  void set_state(int i) { state_ = i; }
+
+  void operator()(T* p) { delete[] p; }
 };
 
 #endif
 
 template <class T>
-void
-swap(Deleter<T>& x, Deleter<T>& y)
-{
-    Deleter<T> t(std::move(x));
-    x = std::move(y);
-    y = std::move(t);
+TEST_CONSTEXPR_CXX23 void swap(Deleter<T>& x, Deleter<T>& y) {
+  Deleter<T> t(std::move(x));
+  x = std::move(y);
+  y = std::move(t);
 }
 
-
 template <class T>
-class CDeleter
-{
-    int state_;
+class CDeleter {
+  int state_;
 
 public:
+  TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~CDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    CDeleter() : state_(0) {}
-    explicit CDeleter(int s) : state_(s) {}
-    ~CDeleter() {assert(state_ >= 0); state_ = -1;}
-
-    template <class U>
-        CDeleter(const CDeleter<U>& d)
-            : state_(d.state()) {}
+  template <class U>
+  TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter<U>& d) : state_(d.state()) {}
 
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) {delete p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; }
 };
 
 template <class T>
-class CDeleter<T[]>
-{
-    int state_;
+class CDeleter<T[]> {
+  int state_;
 
 public:
+  TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {}
+  template <class U>
+  TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter<U>& d) : state_(d.state()) {}
 
-    CDeleter() : state_(0) {}
-    explicit CDeleter(int s) : state_(s) {}
-    template <class U>
-        CDeleter(const CDeleter<U>& d)
-            : state_(d.state()) {}
-
-    ~CDeleter() {assert(state_ >= 0); state_ = -1;}
+  TEST_CONSTEXPR_CXX23 ~CDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) {delete [] p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; }
 };
 
 template <class T>
-void
-swap(CDeleter<T>& x, CDeleter<T>& y)
-{
-    CDeleter<T> t(std::move(x));
-    x = std::move(y);
-    y = std::move(t);
+TEST_CONSTEXPR_CXX23 void swap(CDeleter<T>& x, CDeleter<T>& y) {
+  CDeleter<T> t(std::move(x));
+  x = std::move(y);
+  y = std::move(t);
 }
 
 // Non-copyable deleter
 template <class T>
-class NCDeleter
-{
-    int state_;
-    NCDeleter(NCDeleter const&);
-    NCDeleter& operator=(NCDeleter const&);
-public:
+class NCDeleter {
+  int state_;
+  NCDeleter(NCDeleter const&);
+  NCDeleter& operator=(NCDeleter const&);
 
-    NCDeleter() : state_(0) {}
-    explicit NCDeleter(int s) : state_(s) {}
-    ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
+public:
+  TEST_CONSTEXPR_CXX23 NCDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit NCDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~NCDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) {delete p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; }
 };
 
-
 template <class T>
-class NCDeleter<T[]>
-{
-    int state_;
-    NCDeleter(NCDeleter const&);
-    NCDeleter& operator=(NCDeleter const&);
-public:
+class NCDeleter<T[]> {
+  int state_;
+  NCDeleter(NCDeleter const&);
+  NCDeleter& operator=(NCDeleter const&);
 
-    NCDeleter() : state_(0) {}
-    explicit NCDeleter(int s) : state_(s) {}
-    ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
+public:
+  TEST_CONSTEXPR_CXX23 NCDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit NCDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~NCDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) {delete [] p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; }
 };
 
-
 // Non-copyable deleter
 template <class T>
-class NCConstDeleter
-{
-    int state_;
-    NCConstDeleter(NCConstDeleter const&);
-    NCConstDeleter& operator=(NCConstDeleter const&);
-public:
+class NCConstDeleter {
+  int state_;
+  NCConstDeleter(NCConstDeleter const&);
+  NCConstDeleter& operator=(NCConstDeleter const&);
 
-    NCConstDeleter() : state_(0) {}
-    explicit NCConstDeleter(int s) : state_(s) {}
-    ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
+public:
+  TEST_CONSTEXPR_CXX23 NCConstDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit NCConstDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~NCConstDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) const {delete p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) const { delete p; }
 };
 
-
 template <class T>
-class NCConstDeleter<T[]>
-{
-    int state_;
-    NCConstDeleter(NCConstDeleter const&);
-    NCConstDeleter& operator=(NCConstDeleter const&);
-public:
+class NCConstDeleter<T[]> {
+  int state_;
+  NCConstDeleter(NCConstDeleter const&);
+  NCConstDeleter& operator=(NCConstDeleter const&);
 
-    NCConstDeleter() : state_(0) {}
-    explicit NCConstDeleter(int s) : state_(s) {}
-    ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
+public:
+  TEST_CONSTEXPR_CXX23 NCConstDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit NCConstDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~NCConstDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
 
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
 
-    void operator()(T* p) const {delete [] p;}
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) const { delete[] p; }
 };
 
-
 // Non-copyable deleter
 template <class T>
-class CopyDeleter
-{
-    int state_;
-public:
+class CopyDeleter {
+  int state_;
 
-    CopyDeleter() : state_(0) {}
-    explicit CopyDeleter(int s) : state_(s) {}
-    ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
-
-    CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
-    CopyDeleter& operator=(CopyDeleter const& other) {
-        state_ = other.state_;
-        return *this;
-    }
-
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
-
-    void operator()(T* p) {delete p;}
+public:
+  TEST_CONSTEXPR_CXX23 CopyDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit CopyDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~CopyDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
+
+  TEST_CONSTEXPR_CXX23 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
+  TEST_CONSTEXPR_CXX23 CopyDeleter& operator=(CopyDeleter const& other) {
+    state_ = other.state_;
+    return *this;
+  }
+
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
+
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; }
 };
 
-
 template <class T>
-class CopyDeleter<T[]>
-{
-    int state_;
+class CopyDeleter<T[]> {
+  int state_;
 
 public:
-
-    CopyDeleter() : state_(0) {}
-    explicit CopyDeleter(int s) : state_(s) {}
-    ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
-
-    CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
-    CopyDeleter& operator=(CopyDeleter const& other) {
-        state_ = other.state_;
-        return *this;
-    }
-
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
-
-    void operator()(T* p) {delete [] p;}
+  TEST_CONSTEXPR_CXX23 CopyDeleter() : state_(0) {}
+  TEST_CONSTEXPR_CXX23 explicit CopyDeleter(int s) : state_(s) {}
+  TEST_CONSTEXPR_CXX23 ~CopyDeleter() {
+    assert(state_ >= 0);
+    state_ = -1;
+  }
+
+  TEST_CONSTEXPR_CXX23 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
+  TEST_CONSTEXPR_CXX23 CopyDeleter& operator=(CopyDeleter const& other) {
+    state_ = other.state_;
+    return *this;
+  }
+
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; }
+
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; }
 };
 
-
-struct test_deleter_base
-{
-    static int count;
-    static int dealloc_count;
+struct test_deleter_base {
+  static int count;
+  static int dealloc_count;
 };
 
-int test_deleter_base::count = 0;
+int test_deleter_base::count         = 0;
 int test_deleter_base::dealloc_count = 0;
 
 template <class T>
-class test_deleter
-    : public test_deleter_base
-{
-    int state_;
+class test_deleter : public test_deleter_base {
+  int state_;
 
 public:
-
-    test_deleter() : state_(0) {++count;}
-    explicit test_deleter(int s) : state_(s) {++count;}
-    test_deleter(const test_deleter& d)
-        : state_(d.state_) {++count;}
-    ~test_deleter() {assert(state_ >= 0); --count; state_ = -1;}
-
-    int state() const {return state_;}
-    void set_state(int i) {state_ = i;}
-
-    void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;}
+  test_deleter() : state_(0) { ++count; }
+  explicit test_deleter(int s) : state_(s) { ++count; }
+  test_deleter(const test_deleter& d) : state_(d.state_) { ++count; }
+  ~test_deleter() {
+    assert(state_ >= 0);
+    --count;
+    state_ = -1;
+  }
+
+  int state() const { return state_; }
+  void set_state(int i) { state_ = i; }
+
+  void operator()(T* p) {
+    assert(state_ >= 0);
+    ++dealloc_count;
+    delete p;
+  }
 #if TEST_STD_VER >= 11
-    test_deleter* operator&() const = delete;
+  test_deleter* operator&() const = delete;
 #else
+
 private:
   test_deleter* operator&() const;
 #endif
 };
 
 template <class T>
-void
-swap(test_deleter<T>& x, test_deleter<T>& y)
-{
-    test_deleter<T> t(std::move(x));
-    x = std::move(y);
-    y = std::move(t);
+void swap(test_deleter<T>& x, test_deleter<T>& y) {
+  test_deleter<T> t(std::move(x));
+  x = std::move(y);
+  y = std::move(t);
 }
 
 #if TEST_STD_VER >= 11
 
 template <class T, size_t ID = 0>
-class PointerDeleter
-{
-    PointerDeleter(const PointerDeleter&);
-    PointerDeleter& operator=(const PointerDeleter&);
+class PointerDeleter {
+  PointerDeleter(const PointerDeleter&);
+  PointerDeleter& operator=(const PointerDeleter&);
 
 public:
-    typedef min_pointer<T, std::integral_constant<size_t, ID>> pointer;
+  typedef min_pointer<T, std::integral_constant<size_t, ID>> pointer;
 
-    PointerDeleter() = default;
-    PointerDeleter(PointerDeleter&&) = default;
-    PointerDeleter& operator=(PointerDeleter&&) = default;
-    explicit PointerDeleter(int) {}
+  TEST_CONSTEXPR_CXX23 PointerDeleter()                            = default;
+  TEST_CONSTEXPR_CXX23 PointerDeleter(PointerDeleter&&)            = default;
+  TEST_CONSTEXPR_CXX23 PointerDeleter& operator=(PointerDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 explicit PointerDeleter(int) {}
 
-    template <class U>
-        PointerDeleter(PointerDeleter<U, ID>&&,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
-    {}
+  template <class U>
+  TEST_CONSTEXPR_CXX23
+  PointerDeleter(PointerDeleter<U, ID>&&, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) {}
 
-    void operator()(pointer p) { if (p) { delete std::addressof(*p); }}
+  TEST_CONSTEXPR_CXX23 void operator()(pointer p) {
+    if (p) {
+      delete std::addressof(*p);
+    }
+  }
 
 private:
-    template <class U>
-        PointerDeleter(const PointerDeleter<U, ID>&,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
+  template <class U>
+  PointerDeleter(const PointerDeleter<U, ID>&, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
 };
 
-
 template <class T, size_t ID>
-class PointerDeleter<T[], ID>
-{
-    PointerDeleter(const PointerDeleter&);
-    PointerDeleter& operator=(const PointerDeleter&);
+class PointerDeleter<T[], ID> {
+  PointerDeleter(const PointerDeleter&);
+  PointerDeleter& operator=(const PointerDeleter&);
 
 public:
-    typedef min_pointer<T, std::integral_constant<size_t, ID> > pointer;
+  typedef min_pointer<T, std::integral_constant<size_t, ID> > pointer;
 
-    PointerDeleter() = default;
-    PointerDeleter(PointerDeleter&&) = default;
-    PointerDeleter& operator=(PointerDeleter&&) = default;
-    explicit PointerDeleter(int) {}
+  TEST_CONSTEXPR_CXX23 PointerDeleter()                            = default;
+  TEST_CONSTEXPR_CXX23 PointerDeleter(PointerDeleter&&)            = default;
+  TEST_CONSTEXPR_CXX23 PointerDeleter& operator=(PointerDeleter&&) = default;
+  TEST_CONSTEXPR_CXX23 explicit PointerDeleter(int) {}
 
-    template <class U>
-        PointerDeleter(PointerDeleter<U, ID>&&,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
-    {}
+  template <class U>
+  TEST_CONSTEXPR_CXX23
+  PointerDeleter(PointerDeleter<U, ID>&&, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) {}
 
-    void operator()(pointer p) { if (p) { delete [] std::addressof(*p); }}
+  TEST_CONSTEXPR_CXX23 void operator()(pointer p) {
+    if (p) {
+      delete[] std::addressof(*p);
+    }
+  }
 
 private:
-    template <class U>
-        PointerDeleter(const PointerDeleter<U, ID>&,
-            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
+  template <class U>
+  PointerDeleter(const PointerDeleter<U, ID>&, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
 };
 
 #endif // TEST_STD_VER >= 11
 
 template <class T>
-class DefaultCtorDeleter
-{
-    int state_;
+class DefaultCtorDeleter {
+  int state_;
 
 public:
-    int state() const {return state_;}
-    void operator()(T* p) {delete p;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; }
 };
 
 template <class T>
-class DefaultCtorDeleter<T[]>
-{
-    int state_;
+class DefaultCtorDeleter<T[]> {
+  int state_;
 
 public:
-    int state() const {return state_;}
-    void operator()(T* p) {delete [] p;}
+  TEST_CONSTEXPR_CXX23 int state() const { return state_; }
+  TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; }
 };
 
 #endif // SUPPORT_DELETER_TYPES_H

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index e3d1590e90fa1..7f7c6832a2565 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -166,7 +166,7 @@
 # define TEST_CONSTEXPR_CXX20
 #endif
 
-#if TEST_STD_VER > 20
+#if TEST_STD_VER >= 23
 #  define TEST_CONSTEXPR_CXX23 constexpr
 #else
 #  define TEST_CONSTEXPR_CXX23

diff  --git a/libcxx/test/support/unique_ptr_test_helper.h b/libcxx/test/support/unique_ptr_test_helper.h
index 83c41a4c93937..633ea9740745d 100644
--- a/libcxx/test/support/unique_ptr_test_helper.h
+++ b/libcxx/test/support/unique_ptr_test_helper.h
@@ -17,32 +17,48 @@
 
 struct A {
   static int count;
-  A() { ++count; }
-  A(const A&) { ++count; }
-  virtual ~A() { --count; }
+  TEST_CONSTEXPR_CXX23 A() {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 A(const A&) {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 virtual ~A() {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      --count;
+  }
 };
 
 int A::count = 0;
 
 struct B : public A {
   static int count;
-  B() { ++count; }
-  B(const B& other) : A(other) { ++count; }
-  virtual ~B() { --count; }
+  TEST_CONSTEXPR_CXX23 B() {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 B(const B& other) : A(other) {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      ++count;
+  }
+  TEST_CONSTEXPR_CXX23 virtual ~B() {
+    if (!TEST_IS_CONSTANT_EVALUATED)
+      --count;
+  }
 };
 
 int B::count = 0;
 
 template <class T>
-typename std::enable_if<!std::is_array<T>::value, T*>::type
-newValue(int num_elements) {
+TEST_CONSTEXPR_CXX23 typename std::enable_if<!std::is_array<T>::value, T*>::type newValue(int num_elements) {
   assert(num_elements == 1);
   return new T;
 }
 
 template <class T>
-typename std::enable_if<std::is_array<T>::value,
-                        typename std::remove_all_extents<T>::type*>::type
+TEST_CONSTEXPR_CXX23 typename std::enable_if<std::is_array<T>::value, typename std::remove_all_extents<T>::type*>::type
 newValue(int num_elements) {
   typedef typename std::remove_all_extents<T>::type VT;
   assert(num_elements >= 1);
@@ -57,33 +73,34 @@ IncompleteType* getNewIncomplete();
 IncompleteType* getNewIncompleteArray(int size);
 
 #if TEST_STD_VER >= 11
-template <class ThisT, class ...Args>
+template <class ThisT, class... Args>
 struct args_is_this_type : std::false_type {};
 
 template <class ThisT, class A1>
 struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};
 #endif
 
-template <class IncompleteT = IncompleteType,
-          class Del = std::default_delete<IncompleteT> >
+template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT> >
 struct StoresIncomplete {
-  static_assert((std::is_same<IncompleteT, IncompleteType>::value ||
-                 std::is_same<IncompleteT, IncompleteType[]>::value), "");
+  static_assert(
+      (std::is_same<IncompleteT, IncompleteType>::value || std::is_same<IncompleteT, IncompleteType[]>::value), "");
 
   std::unique_ptr<IncompleteT, Del> m_ptr;
 
 #if TEST_STD_VER >= 11
   StoresIncomplete(StoresIncomplete const&) = delete;
-  StoresIncomplete(StoresIncomplete&&) = default;
+  StoresIncomplete(StoresIncomplete&&)      = default;
 
-  template <class ...Args>
+  template <class... Args>
   StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {
     static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");
   }
 #else
+
 private:
   StoresIncomplete();
   StoresIncomplete(StoresIncomplete const&);
+
 public:
 #endif
 
@@ -94,8 +111,7 @@ struct StoresIncomplete {
 };
 
 #if TEST_STD_VER >= 11
-template <class IncompleteT = IncompleteType,
-          class Del = std::default_delete<IncompleteT>, class... Args>
+template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT>, class... Args>
 void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
   checkNumIncompleteTypeAlive(expect_alive);
   {
@@ -110,38 +126,34 @@ void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
 }
 #endif
 
-#define INCOMPLETE_TEST_EPILOGUE()                                             \
-  int is_incomplete_test_anchor = is_incomplete_test();                        \
-                                                                               \
-  struct IncompleteType {                                                      \
-    static int count;                                                          \
-    IncompleteType() { ++count; }                                              \
-    ~IncompleteType() { --count; }                                             \
-  };                                                                           \
-                                                                               \
-  int IncompleteType::count = 0;                                               \
-                                                                               \
-  void checkNumIncompleteTypeAlive(int i) {                                    \
-    assert(IncompleteType::count == i);                                        \
-  }                                                                            \
-  int getNumIncompleteTypeAlive() { return IncompleteType::count; }            \
-  IncompleteType* getNewIncomplete() { return new IncompleteType; }            \
-  IncompleteType* getNewIncompleteArray(int size) {                            \
-    return new IncompleteType[size];                                           \
-  }                                                                            \
-                                                                               \
-  template <class IncompleteT, class Del>                                      \
+#define INCOMPLETE_TEST_EPILOGUE()                                                                                     \
+  int is_incomplete_test_anchor = is_incomplete_test();                                                                \
+                                                                                                                       \
+  struct IncompleteType {                                                                                              \
+    static int count;                                                                                                  \
+    IncompleteType() { ++count; }                                                                                      \
+    ~IncompleteType() { --count; }                                                                                     \
+  };                                                                                                                   \
+                                                                                                                       \
+  int IncompleteType::count = 0;                                                                                       \
+                                                                                                                       \
+  void checkNumIncompleteTypeAlive(int i) { assert(IncompleteType::count == i); }                                      \
+  int getNumIncompleteTypeAlive() { return IncompleteType::count; }                                                    \
+  IncompleteType* getNewIncomplete() { return new IncompleteType; }                                                    \
+  IncompleteType* getNewIncompleteArray(int size) { return new IncompleteType[size]; }                                 \
+                                                                                                                       \
+  template <class IncompleteT, class Del>                                                                              \
   StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
 #
 
 #if TEST_STD_VER >= 11
-#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                 \
-  static int is_incomplete_test() { __VA_ARGS__ return 0; }                    \
-  INCOMPLETE_TEST_EPILOGUE()
+#  define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                                                       \
+    static int is_incomplete_test() { __VA_ARGS__ return 0; }                                                          \
+    INCOMPLETE_TEST_EPILOGUE()
 #else
-#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                 \
-  static int is_incomplete_test() { return 0; }                                \
-  INCOMPLETE_TEST_EPILOGUE()
+#  define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                                                       \
+    static int is_incomplete_test() { return 0; }                                                                      \
+    INCOMPLETE_TEST_EPILOGUE()
 #endif
 
 #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 38b04d261e484..41e85980bc8ff 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -242,7 +242,7 @@ def add_version_header(tc):
     "headers": ["iterator"],
   }, {
     "name": "__cpp_lib_constexpr_memory",
-    "values": { "c++20": 201811 },
+    "values": { "c++20": 201811, "c++2b": 202202 },
     "headers": ["memory"],
   }, {
     "name": "__cpp_lib_constexpr_numeric",


        


More information about the libcxx-commits mailing list