diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv
--- a/libcxx/docs/Status/Cxx20Papers.csv
+++ b/libcxx/docs/Status/Cxx20Papers.csv
@@ -106,7 +106,7 @@
 "`P0645R10 <https://wg21.link/P0645R10>`__","LWG","Text Formatting","Cologne","|In Progress|",""
 "`P0660R10 <https://wg21.link/P0660R10>`__","LWG","Stop Token and Joining Thread, Rev 10","Cologne","",""
 "`P0784R7 <https://wg21.link/P0784R7>`__","CWG","More constexpr containers","Cologne","|Complete|","12.0"
-"`P0980R1 <https://wg21.link/P0980R1>`__","LWG","Making std::string constexpr","Cologne","",""
+"`P0980R1 <https://wg21.link/P0980R1>`__","LWG","Making std::string constexpr","Cologne","|Complete|","14.0"
 "`P1004R2 <https://wg21.link/P1004R2>`__","LWG","Making std::vector constexpr","Cologne","",""
 "`P1035R7 <https://wg21.link/P1035R7>`__","LWG","Input Range Adaptors","Cologne","",""
 "`P1065R2 <https://wg21.link/P1065R2>`__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0"
diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h
--- a/libcxx/include/__memory/compressed_pair.h
+++ b/libcxx/include/__memory/compressed_pair.h
@@ -58,10 +58,8 @@
       : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
 #endif
 
-
-  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
-  _LIBCPP_INLINE_VISIBILITY
-  const_reference __get() const _NOEXCEPT { return __value_; }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference __get() _NOEXCEPT { return __value_; }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return __value_; }
 
 private:
   _Tp __value_;
@@ -97,9 +95,8 @@
       : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
 #endif
 
-  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
-  _LIBCPP_INLINE_VISIBILITY
-  const_reference __get() const _NOEXCEPT { return *this; }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 reference __get() _NOEXCEPT { return *this; }
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __get() const _NOEXCEPT { return *this; }
 };
 
 template <class _T1, class _T2>
@@ -143,23 +140,19 @@
                typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
 #endif
 
-  _LIBCPP_INLINE_VISIBILITY
-  typename _Base1::reference first() _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename _Base1::reference first() _NOEXCEPT {
     return static_cast<_Base1&>(*this).__get();
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  typename _Base1::const_reference first() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base1::const_reference first() const _NOEXCEPT {
     return static_cast<_Base1 const&>(*this).__get();
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  typename _Base2::reference second() _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename _Base2::reference second() _NOEXCEPT {
     return static_cast<_Base2&>(*this).__get();
   }
 
-  _LIBCPP_INLINE_VISIBILITY
-  typename _Base2::const_reference second() const _NOEXCEPT {
+  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename _Base2::const_reference second() const _NOEXCEPT {
     return static_cast<_Base2 const&>(*this).__get();
   }
 
diff --git a/libcxx/include/__string b/libcxx/include/__string
--- a/libcxx/include/__string
+++ b/libcxx/include/__string
@@ -293,22 +293,25 @@
 
 template <class _CharT>
 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
+_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
 {
-    if (__n == 0) return __s1;
-    if (__s1 < __s2) {
-      _VSTD::copy(__s2, __s2 + __n, __s1);
-    } else if (__s2 < __s1) {
-      _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n);
-    }
+    _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), 
+                   "__copy_constexpr should always be constant evaluated");
+    _VSTD::copy_n(__s2, __n, __s1);
     return __s1;
 }
 
 template <class _CharT>
 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
-_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
+_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT
 {
-    _VSTD::copy_n(__s2, __n, __s1);
+    _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), 
+                   "__move_constexpr should always be constant evaluated");
+    if (__n == 0) return __s1;
+    _CharT* __alloc = new _CharT[__n];
+    _VSTD::__copy_constexpr(__alloc, __s2, __n);
+    _VSTD::__copy_constexpr(__s1, static_cast<const _CharT*>(__alloc), __n);
+    delete[] __alloc;
     return __s1;
 }
 
@@ -316,6 +319,8 @@
 static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 _CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT
 {
+    _LIBCPP_ASSERT(__libcpp_is_constant_evaluated(), 
+                   "__move_constexpr should always be constant evaluated");
      _VSTD::fill_n(__s, __n, __a);
      return __s;
 }
@@ -334,14 +339,17 @@
     static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
     static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
-            {return __c1 == __c2;}
+        {return __c1 == __c2;}
     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return (unsigned char)__c1 < (unsigned char)__c2;}
 
     static _LIBCPP_CONSTEXPR_AFTER_CXX14
     int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
-    static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
-    length(const char_type* __s)  _NOEXCEPT {return __builtin_strlen(__s);}
+
+    static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14 length(const char_type* __s)  _NOEXCEPT {
+      return __builtin_strlen(__s);
+    }
+
     static _LIBCPP_CONSTEXPR_AFTER_CXX14
     const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
     static inline _LIBCPP_CONSTEXPR_AFTER_CXX17
diff --git a/libcxx/include/memory b/libcxx/include/memory
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -669,6 +669,7 @@
 
 */
 
+#include "__config"
 #include <__config>
 #include <__functional_base>
 #include <__memory/addressof.h>
@@ -840,7 +841,7 @@
 
 // --- Helper for container swap --
 template <typename _Alloc>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
 #if _LIBCPP_STD_VER >= 14
     _NOEXCEPT
@@ -853,11 +854,11 @@
 }
 
 template <typename _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
 
 template <typename _Alloc>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void __swap_allocator(_Alloc & __a1, _Alloc & __a2)
 #if _LIBCPP_STD_VER >= 14
     _NOEXCEPT
diff --git a/libcxx/include/string b/libcxx/include/string
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -519,6 +519,7 @@
 #include <__debug>
 #include <__functional_base>
 #include <__iterator/wrap_iter.h>
+#include <__memory/construct_at.h>
 #include <algorithm>
 #include <compare>
 #include <cstdio>  // EOF
@@ -592,24 +593,28 @@
 // basic_string
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
           const basic_string<_CharT, _Traits, _Allocator>& __y);
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
 
@@ -703,8 +708,8 @@
 
     typedef __wrap_iter<pointer>                         iterator;
     typedef __wrap_iter<const_pointer>                   const_iterator;
-    typedef _VSTD::reverse_iterator<iterator>             reverse_iterator;
-    typedef _VSTD::reverse_iterator<const_iterator>       const_reverse_iterator;
+    typedef _VSTD::reverse_iterator<iterator>            reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>      const_reverse_iterator;
 
 private:
 
@@ -795,21 +800,24 @@
     _LIBCPP_TEMPLATE_DATA_VIS
     static const size_type npos = -1;
 
-    _LIBCPP_INLINE_VISIBILITY basic_string()
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
 
-    _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    explicit basic_string(const allocator_type& __a)
 #if _LIBCPP_STD_VER <= 14
         _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
 #else
         _NOEXCEPT;
 #endif
 
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const basic_string& __str);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const basic_string& __str, const allocator_type& __a);
 
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(basic_string&& __str)
 #if _LIBCPP_STD_VER <= 14
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
@@ -817,12 +825,12 @@
         _NOEXCEPT;
 #endif
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(basic_string&& __str, const allocator_type& __a);
 #endif // _LIBCPP_CXX03_LANG
 
     template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
       _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
       __init(__s, traits_type::length(__s));
@@ -832,80 +840,84 @@
     }
 
     template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         basic_string(const _CharT* __s, const _Allocator& __a);
 
 #if _LIBCPP_STD_VER > 20
     basic_string(nullptr_t) = delete;
 #endif
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const _CharT* __s, size_type __n);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(size_type __n, _CharT __c);
 
     template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         basic_string(size_type __n, _CharT __c, const _Allocator& __a);
 
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const basic_string& __str, size_type __pos, size_type __n,
                  const _Allocator& __a = _Allocator());
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(const basic_string& __str, size_type __pos,
                  const _Allocator& __a = _Allocator());
 
     template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
         basic_string(const _Tp& __t, size_type __pos, size_type __n,
                      const allocator_type& __a = allocator_type());
 
     template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                                           !__is_same_uncvref<_Tp, basic_string>::value> >
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
         explicit basic_string(const _Tp& __t);
 
     template<class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
-        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
         explicit basic_string(const _Tp& __t, const allocator_type& __a);
 
     template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         basic_string(_InputIterator __first, _InputIterator __last);
     template<class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(initializer_list<_CharT> __il);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
 #endif // _LIBCPP_CXX03_LANG
 
-    inline ~basic_string();
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 inline ~basic_string();
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
 
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& operator=(const basic_string& __str);
 
     template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& operator=(const _Tp& __t)
         {__self_view __sv = __t; return assign(__sv);}
 
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& operator=(basic_string&& __str)
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
-     _LIBCPP_INLINE_VISIBILITY
+     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
 #endif
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    basic_string& operator=(const value_type* __s) {return assign(__s);}
 #if _LIBCPP_STD_VER > 20
     basic_string& operator=(nullptr_t) = delete;
 #endif
-    basic_string& operator=(value_type __c);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& operator=(value_type __c);
 
 #if _LIBCPP_DEBUG_LEVEL == 2
     _LIBCPP_INLINE_VISIBILITY
@@ -921,106 +933,112 @@
     const_iterator end() const _NOEXCEPT
         {return const_iterator(this, __get_pointer() + size());}
 #else
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     iterator begin() _NOEXCEPT
         {return iterator(__get_pointer());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_iterator begin() const _NOEXCEPT
         {return const_iterator(__get_pointer());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     iterator end() _NOEXCEPT
         {return iterator(__get_pointer() + size());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_iterator end() const _NOEXCEPT
         {return const_iterator(__get_pointer() + size());}
 #endif // _LIBCPP_DEBUG_LEVEL == 2
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     reverse_iterator rbegin() _NOEXCEPT
         {return reverse_iterator(end());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_reverse_iterator rbegin() const _NOEXCEPT
         {return const_reverse_iterator(end());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     reverse_iterator rend() _NOEXCEPT
         {return reverse_iterator(begin());}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_reverse_iterator rend() const _NOEXCEPT
         {return const_reverse_iterator(begin());}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_iterator cbegin() const _NOEXCEPT
         {return begin();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_iterator cend() const _NOEXCEPT
         {return end();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_reverse_iterator crbegin() const _NOEXCEPT
         {return rbegin();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_reverse_iterator crend() const _NOEXCEPT
         {return rend();}
 
-    _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type size() const _NOEXCEPT
         {return __is_long() ? __get_long_size() : __get_short_size();}
-    _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
-    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
-        {return (__is_long() ? __get_long_cap()
-                             : static_cast<size_type>(__min_cap)) - 1;}
 
-    void resize(size_type __n, value_type __c);
-    _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type length() const _NOEXCEPT {return size();}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type max_size() const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type capacity() const _NOEXCEPT
+        {return (__is_long() ? __get_long_cap() : static_cast<size_type>(__min_cap)) - 1;}
+
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n, value_type __c);
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void resize(size_type __n) {resize(__n, value_type());}
 
-    void reserve(size_type __requested_capacity);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void reserve(size_type __requested_capacity);
     _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n);
 
-    _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
-    void reserve() _NOEXCEPT {shrink_to_fit();}
-    _LIBCPP_INLINE_VISIBILITY
-    void shrink_to_fit() _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
-    void clear() _NOEXCEPT;
-    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY void reserve() _NOEXCEPT {shrink_to_fit();}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void shrink_to_fit() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void clear() _NOEXCEPT;
+
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     bool empty() const _NOEXCEPT {return size() == 0;}
 
-    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __pos)       _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    const_reference operator[](size_type __pos) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    reference       operator[](size_type __pos)       _NOEXCEPT;
 
-    const_reference at(size_type __n) const;
-    reference       at(size_type __n);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference at(size_type __n) const;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 reference       at(size_type __n);
 
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    basic_string& operator+=(const basic_string& __str) {return append(__str);}
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
             && !__is_same_uncvref<_Tp, basic_string >::value,
             basic_string&
         >
-                                            operator+=(const _Tp& __t)            {__self_view __sv = __t; return append(__sv);}
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)     {return append(__s);}
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;}
+        operator+=(const _Tp& __t) {__self_view __sv = __t; return append(__sv);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    basic_string& operator+=(const value_type* __s) {return append(__s);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
 #endif // _LIBCPP_CXX03_LANG
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& append(const basic_string& __str);
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t<
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
             && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
         >
                   append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -1028,9 +1046,9 @@
             basic_string&
         >
                   append(const _Tp& __t, size_type __pos, size_type __n=npos);
-    basic_string& append(const value_type* __s, size_type __n);
-    basic_string& append(const value_type* __s);
-    basic_string& append(size_type __n, value_type __c);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s, size_type __n);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(const value_type* __s);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& append(size_type __n, value_type __c);
 
     _LIBCPP_INLINE_VISIBILITY
     void __append_default_init(size_type __n);
@@ -1042,7 +1060,7 @@
             __is_exactly_cpp17_input_iterator<_InputIterator>::value,
             basic_string&
         >
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     append(_InputIterator __first, _InputIterator __last) {
       const basic_string __temp(__first, __last, __alloc());
       append(__temp.data(), __temp.size());
@@ -1055,41 +1073,41 @@
             __is_cpp17_forward_iterator<_ForwardIterator>::value,
             basic_string&
         >
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     append(_ForwardIterator __first, _ForwardIterator __last);
 
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
 #endif // _LIBCPP_CXX03_LANG
 
-    void push_back(value_type __c);
-    _LIBCPP_INLINE_VISIBILITY
-    void pop_back();
-    _LIBCPP_INLINE_VISIBILITY reference       front() _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY const_reference front() const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY reference       back() _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY const_reference back() const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void push_back(value_type __c);
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void pop_back();
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference front() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference front() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reference back() const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             basic_string&
         >
                  assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(const basic_string& __str) { return *this = __str; }
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(basic_string&& __str)
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
         {*this = _VSTD::move(__str); return *this;}
 #endif
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -1097,11 +1115,14 @@
             basic_string&
         >
                   assign(const _Tp & __t, size_type __pos, size_type __n=npos);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(const value_type* __s, size_type __n);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(const value_type* __s);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(size_type __n, value_type __c);
     template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -1109,7 +1130,7 @@
         >
         assign(_InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -1117,15 +1138,15 @@
         >
         assign(_ForwardIterator __first, _ForwardIterator __last);
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
 #endif // _LIBCPP_CXX03_LANG
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& insert(size_type __pos1, const basic_string& __str);
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1135,22 +1156,23 @@
     { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
         >
                   insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
-    basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
-    basic_string& insert(size_type __pos, const value_type* __s);
-    basic_string& insert(size_type __pos, size_type __n, value_type __c);
-    iterator      insert(const_iterator __pos, value_type __c);
-    _LIBCPP_INLINE_VISIBILITY
-    iterator      insert(const_iterator __pos, size_type __n, value_type __c);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, const value_type* __s);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& insert(size_type __pos, size_type __n, value_type __c);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator      insert(const_iterator __pos, value_type __c);
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    iterator insert(const_iterator __pos, size_type __n, value_type __c);
     template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -1158,7 +1180,7 @@
         >
         insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
     template<class _ForwardIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -1166,45 +1188,49 @@
         >
         insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     iterator insert(const_iterator __pos, initializer_list<value_type> __il)
                     {return insert(__pos, __il.begin(), __il.end());}
 #endif // _LIBCPP_CXX03_LANG
 
-    basic_string& erase(size_type __pos = 0, size_type __n = npos);
-    _LIBCPP_INLINE_VISIBILITY
-    iterator      erase(const_iterator __pos);
-    _LIBCPP_INLINE_VISIBILITY
-    iterator      erase(const_iterator __first, const_iterator __last);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string& erase(size_type __pos = 0, size_type __n = npos);
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator erase(const_iterator __pos);
+    
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    iterator erase(const_iterator __first, const_iterator __last);
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             basic_string&
         >
                   replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
             basic_string&
         >
                   replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1212,14 +1238,14 @@
         >
                   replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
     template<class _InputIterator>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __is_cpp17_input_iterator<_InputIterator>::value,
@@ -1227,17 +1253,16 @@
         >
         replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
         {return replace(__i1, __i2, __il.begin(), __il.end());}
 #endif // _LIBCPP_CXX03_LANG
 
-    size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string substr(size_type __pos = 0, size_type __n = npos) const;
 
-    _LIBCPP_INLINE_VISIBILITY
-    void swap(basic_string& __str)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(basic_string& __str)
 #if _LIBCPP_STD_VER >= 14
         _NOEXCEPT;
 #else
@@ -1245,123 +1270,131 @@
                     __is_nothrow_swappable<allocator_type>::value);
 #endif
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const value_type* c_str() const _NOEXCEPT {return data();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const value_type* data() const _NOEXCEPT  {return _VSTD::__to_address(__get_pointer());}
 #if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY)
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     value_type* data()             _NOEXCEPT  {return _VSTD::__to_address(__get_pointer());}
 #endif
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
         >
               find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
         >
               rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
         >
               find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
         >
               find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+              _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
         >
               find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
             size_type
         >
               find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     int compare(const basic_string& __str) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1370,7 +1403,7 @@
         compare(const _Tp &__t) const _NOEXCEPT;
 
     template <class _Tp>
-    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
+    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -1378,20 +1411,22 @@
         >
          compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;
 
     template <class _Tp>
-    inline _LIBCPP_INLINE_VISIBILITY
+    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         __enable_if_t
         <
             __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,
             int
         >
         compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
-    int compare(const value_type* __s) const _NOEXCEPT;
-    int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(const value_type* __s) const _NOEXCEPT;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
 
 #if _LIBCPP_STD_VER > 17
@@ -1434,15 +1469,17 @@
     { return __self_view(data(), size()).contains(__s); }
 #endif
 
-    _LIBCPP_INLINE_VISIBILITY bool __invariants() const;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __invariants() const;
 
-    _LIBCPP_INLINE_VISIBILITY void __clear_and_shrink() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __clear_and_shrink() _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY void __shrink_or_extend(size_type __target_capacity);
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void __shrink_or_extend(size_type __target_capacity);
 
-    _LIBCPP_INLINE_VISIBILITY
-    bool __is_long() const _NOEXCEPT
-        {return bool(__r_.first().__s.__size_ & __short_mask);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool __is_long() const _NOEXCEPT { 
+      if (__libcpp_is_constant_evaluated())
+        return true;
+      return bool(__r_.first().__s.__size_ & __short_mask);
+    }
 
 #if _LIBCPP_DEBUG_LEVEL == 2
 
@@ -1454,10 +1491,10 @@
 #endif // _LIBCPP_DEBUG_LEVEL == 2
 
 private:
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     allocator_type& __alloc() _NOEXCEPT
         {return __r_.second();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const allocator_type& __alloc() const _NOEXCEPT
         {return __r_.second();}
 
@@ -1499,30 +1536,30 @@
 
 #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __set_long_size(size_type __s) _NOEXCEPT
         {__r_.first().__l.__size_ = __s;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type __get_long_size() const _NOEXCEPT
         {return __r_.first().__l.__size_;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __set_size(size_type __s) _NOEXCEPT
         {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __set_long_cap(size_type __s) _NOEXCEPT
         {__r_.first().__l.__cap_  = __long_mask | __s;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type __get_long_cap() const _NOEXCEPT
         {return __r_.first().__l.__cap_ & size_type(~__long_mask);}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __set_long_pointer(pointer __p) _NOEXCEPT
         {__r_.first().__l.__data_ = __p;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     pointer __get_long_pointer() _NOEXCEPT
         {return __r_.first().__l.__data_;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_pointer __get_long_pointer() const _NOEXCEPT
         {return __r_.first().__l.__data_;}
     _LIBCPP_INLINE_VISIBILITY
@@ -1531,41 +1568,46 @@
     _LIBCPP_INLINE_VISIBILITY
     const_pointer __get_short_pointer() const _NOEXCEPT
         {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     pointer __get_pointer() _NOEXCEPT
         {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     const_pointer __get_pointer() const _NOEXCEPT
         {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
 
-    _LIBCPP_INLINE_VISIBILITY
-    void __zero() _NOEXCEPT
-        {
-            size_type (&__a)[__n_words] = __r_.first().__r.__words;
-            for (unsigned __i = 0; __i < __n_words; ++__i)
-                __a[__i] = 0;
-        }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void __zero() _NOEXCEPT {
+      size_type (&__a)[__n_words] = __r_.first().__r.__words;
+      if (__libcpp_is_constant_evaluated()) {
+        __r_.first() = __rep();
+        return;
+      }
+      for (unsigned __i = 0; __i < __n_words; ++__i)
+        __a[__i] = 0;
+    }
 
     template <size_type __a> static
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         size_type __align_it(size_type __s) _NOEXCEPT
             {return (__s + (__a-1)) & ~(__a-1);}
     enum {__alignment = 16};
-    static _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type __recommend(size_type __s) _NOEXCEPT
-        {
+    {
+        if (__libcpp_is_constant_evaluated())
+            return __s + 1;
         if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1;
         size_type __guess = __align_it<sizeof(value_type) < __alignment ?
                      __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
         if (__guess == __min_cap) ++__guess;
         return __guess;
-        }
+    }
 
-    inline
+    inline _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __init(const value_type* __s, size_type __sz, size_type __reserve);
-    inline
+    inline _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __init(const value_type* __s, size_type __sz);
-    inline
+    inline _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __init(size_type __n, value_type __c);
 
     // Slow path for the (inlined) copy constructor for 'long' strings.
@@ -1576,10 +1618,11 @@
     // to call the __init() functions as those are marked as inline which may
     // result in over-aggressive inlining by the compiler, where our aim is
     // to only inline the fast path code directly in the ctor.
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __init_copy_ctor_external(const value_type* __s, size_type __sz);
 
     template <class _InputIterator>
-    inline
+    inline _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
     <
         __is_exactly_cpp17_input_iterator<_InputIterator>::value
@@ -1587,15 +1630,20 @@
     __init(_InputIterator __first, _InputIterator __last);
 
     template <class _ForwardIterator>
-    inline
+    inline _LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
     <
         __is_cpp17_forward_iterator<_ForwardIterator>::value
     >
     __init(_ForwardIterator __first, _ForwardIterator __last);
 
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void __free_memory_constexpr();
+
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                    size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                                size_type __n_copy,  size_type __n_del,
                                size_type __n_add, const value_type* __p_new_stuff);
@@ -1604,21 +1652,25 @@
     // have proof that the input does not alias the current instance.
     // For example, operator=(basic_string) performs a 'self' check.
     template <bool __is_short>
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& __assign_no_alias(const value_type* __s, size_type __n);
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __erase_to_end(size_type __pos);
 
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void __finish_replace(size_type& __sz, size_type& __n1, size_type& __n2, value_type*& __p);
+
     // __erase_external_with_move is invoked for erase() invocations where
     // `n ~= npos`, likely requiring memory moves on the string data.
-    void __erase_external_with_move(size_type __pos, size_type __n);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17 void __erase_external_with_move(size_type __pos, size_type __n);
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __copy_assign_alloc(const basic_string& __str)
         {__copy_assign_alloc(__str, integral_constant<bool,
                       __alloc_traits::propagate_on_container_copy_assignment::value>());}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __copy_assign_alloc(const basic_string& __str, true_type)
         {
             if (__alloc() == __str.__alloc())
@@ -1634,6 +1686,7 @@
                 {
                     allocator_type __a = __str.__alloc();
                     pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap());
+                    __begin_lifetime(__p, __str.__get_long_cap());
                     __clear_and_shrink();
                     __alloc() = _VSTD::move(__a);
                     __set_long_pointer(__p);
@@ -1643,15 +1696,15 @@
             }
         }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
         {}
 
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __move_assign(basic_string& __str, false_type)
         _NOEXCEPT_(__alloc_traits::is_always_equal::value);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __move_assign(basic_string& __str, true_type)
 #if _LIBCPP_STD_VER > 14
         _NOEXCEPT;
@@ -1660,7 +1713,7 @@
 #endif
 #endif
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void
     __move_assign_alloc(basic_string& __str)
         _NOEXCEPT_(
@@ -1669,19 +1722,20 @@
     {__move_assign_alloc(__str, integral_constant<bool,
                       __alloc_traits::propagate_on_container_move_assignment::value>());}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __move_assign_alloc(basic_string& __c, true_type)
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
         {
             __alloc() = _VSTD::move(__c.__alloc());
         }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __move_assign_alloc(basic_string&, false_type)
         _NOEXCEPT
         {}
 
     basic_string& __assign_external(const value_type* __s);
+    _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string& __assign_external(const value_type* __s, size_type __n);
 
     // Assigns the value in __s, guaranteed to be __n < __min_cap in length.
@@ -1694,8 +1748,10 @@
       return *this;
     }
 
-    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
-    _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void __invalidate_all_iterators();
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+    void __invalidate_iterators_past(size_type);
 
     template<class _Tp>
     _LIBCPP_INLINE_VISIBILITY
@@ -1713,7 +1769,7 @@
 #endif
     }
 
-    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
+    _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
     void __throw_out_of_range() const {
 #ifndef _LIBCPP_NO_EXCEPTIONS
         __basic_string_common<true>::__throw_out_of_range();
@@ -1722,11 +1778,29 @@
 #endif
     }
 
-    friend basic_string operator+<>(const basic_string&, const basic_string&);
-    friend basic_string operator+<>(const value_type*, const basic_string&);
-    friend basic_string operator+<>(value_type, const basic_string&);
-    friend basic_string operator+<>(const basic_string&, const value_type*);
-    friend basic_string operator+<>(const basic_string&, value_type);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __begin_lifetime(pointer __p, size_type __count) {
+#if _LIBCPP_STD_VER > 17
+    if (__libcpp_is_constant_evaluated()) {
+      for (size_type __i = 0; __i < __count; ++__i)
+        construct_at(&__p[__i], value_type());
+    }
+#else
+    ((void)__p);
+    ((void)__count);
+#endif
+  }
+
+    template<class _ForwardIterator>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void __insert_not_in_range(size_type __ip,
+                                                                                   size_type __n,
+                                                                                   _ForwardIterator __first,
+                                                                                   _ForwardIterator __last);
+
+    friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const basic_string&);
+    friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const value_type*, const basic_string&);
+    friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(value_type, const basic_string&);
+    friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, const value_type*);
+    friend _LIBCPP_CONSTEXPR_AFTER_CXX17 basic_string operator+<>(const basic_string&, value_type);
 };
 
 // These declarations must appear before any functions are implicitly used
@@ -1773,7 +1847,7 @@
 #endif
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
 {
@@ -1783,7 +1857,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos)
 {
@@ -1811,7 +1885,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string()
     _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
      : __r_(__default_init_tag(), __default_init_tag())
@@ -1819,11 +1893,14 @@
 #if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->__insert_c(this);
 #endif
+  if (__libcpp_is_constant_evaluated())
+    __init(size_type(), value_type());
+  else
     __zero();
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
 #if _LIBCPP_STD_VER <= 14
         _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
@@ -1835,18 +1912,24 @@
 #if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->__insert_c(this);
 #endif
+  if (__libcpp_is_constant_evaluated())
+    __init(size_type(0), value_type());
+  else
     __zero();
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s,
                                                        size_type __sz,
                                                        size_type __reserve)
 {
+    if (__libcpp_is_constant_evaluated())
+        __zero();
     if (__reserve > max_size())
         this->__throw_length_error();
     pointer __p;
-    if (__reserve < __min_cap)
+    if (__reserve < __min_cap && !__libcpp_is_constant_evaluated())
     {
         __set_short_size(__sz);
         __p = __get_short_pointer();
@@ -1855,6 +1938,7 @@
     {
         size_type __cap = __recommend(__reserve);
         __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __begin_lifetime(__p, __cap + 1);
         __set_long_pointer(__p);
         __set_long_cap(__cap+1);
         __set_long_size(__sz);
@@ -1864,31 +1948,16 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
 {
-    if (__sz > max_size())
-        this->__throw_length_error();
-    pointer __p;
-    if (__sz < __min_cap)
-    {
-        __set_short_size(__sz);
-        __p = __get_short_pointer();
-    }
-    else
-    {
-        size_type __cap = __recommend(__sz);
-        __p = __alloc_traits::allocate(__alloc(), __cap+1);
-        __set_long_pointer(__p);
-        __set_long_cap(__cap+1);
-        __set_long_size(__sz);
-    }
-    traits_type::copy(_VSTD::__to_address(__p), __s, __sz);
-    traits_type::assign(__p[__sz], value_type());
+    __init(__s, __sz, __sz);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
     : __r_(__default_init_tag(), __a)
 {
@@ -1900,7 +1969,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
      : __r_(__default_init_tag(), __default_init_tag())
 {
@@ -1912,7 +1981,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
     : __r_(__default_init_tag(), __a)
 {
@@ -1924,6 +1993,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
     : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
 {
@@ -1939,6 +2009,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(
     const basic_string& __str, const allocator_type& __a)
     : __r_(__default_init_tag(), __a)
@@ -1954,10 +2025,13 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
     const value_type* __s, size_type __sz) {
+  if (__libcpp_is_constant_evaluated())
+    __zero();
   pointer __p;
-  if (__sz < __min_cap) {
+  if (__sz < __min_cap && !__libcpp_is_constant_evaluated()) {
     __p = __get_short_pointer();
     __set_short_size(__sz);
   } else {
@@ -1965,6 +2039,7 @@
       this->__throw_length_error();
     size_t __cap = __recommend(__sz);
     __p = __alloc_traits::allocate(__alloc(), __cap + 1);
+    __begin_lifetime(__p, __cap + 1);
     __set_long_pointer(__p);
     __set_long_cap(__cap + 1);
     __set_long_size(__sz);
@@ -1975,7 +2050,7 @@
 #ifndef _LIBCPP_CXX03_LANG
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
 #if _LIBCPP_STD_VER <= 14
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
@@ -1993,7 +2068,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
     : __r_(__default_init_tag(), __a)
 {
@@ -2001,7 +2076,13 @@
         __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
     else
     {
-        __r_.first().__r = __str.__r_.first().__r;
+        if (__libcpp_is_constant_evaluated())
+        {
+            __r_.first() = __rep();
+            __r_.first().__l = __str.__r_.first().__l;
+        }
+        else
+            __r_.first().__r = __str.__r_.first().__r;
         __str.__zero();
     }
 #if _LIBCPP_DEBUG_LEVEL == 2
@@ -2014,13 +2095,16 @@
 #endif // _LIBCPP_CXX03_LANG
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
 {
+    if (__libcpp_is_constant_evaluated())
+        __zero();
     if (__n > max_size())
         this->__throw_length_error();
     pointer __p;
-    if (__n < __min_cap)
+    if (__n < __min_cap && !__libcpp_is_constant_evaluated())
     {
         __set_short_size(__n);
         __p = __get_short_pointer();
@@ -2029,6 +2113,7 @@
     {
         size_type __cap = __recommend(__n);
         __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __begin_lifetime(__p, __cap + 1);
         __set_long_pointer(__p);
         __set_long_cap(__cap+1);
         __set_long_size(__n);
@@ -2038,7 +2123,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
      : __r_(__default_init_tag(), __default_init_tag())
 {
@@ -2049,7 +2134,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-template <class>
+template <class> _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
     : __r_(__default_init_tag(), __a)
 {
@@ -2060,6 +2145,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
                                                         size_type __pos, size_type __n,
                                                         const _Allocator& __a)
@@ -2075,7 +2161,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
                                                         const _Allocator& __a)
     : __r_(__default_init_tag(), __a)
@@ -2091,6 +2177,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp, class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(
              const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a)
     : __r_(__default_init_tag(), __a)
@@ -2105,6 +2192,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp, class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t)
      : __r_(__default_init_tag(), __default_init_tag())
 {
@@ -2117,6 +2205,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp, class>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a)
     : __r_(__default_init_tag(), __a)
 {
@@ -2129,6 +2218,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __is_exactly_cpp17_input_iterator<_InputIterator>::value
@@ -2136,6 +2226,8 @@
 basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
 {
     __zero();
+    if (__libcpp_is_constant_evaluated())
+        __init(size_type(), value_type());
 #ifndef _LIBCPP_NO_EXCEPTIONS
     try
     {
@@ -2155,17 +2247,20 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __is_cpp17_forward_iterator<_ForwardIterator>::value
 >
 basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
 {
+    if (__libcpp_is_constant_evaluated())
+        __zero();
     size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
     if (__sz > max_size())
         this->__throw_length_error();
     pointer __p;
-    if (__sz < __min_cap)
+    if (__sz < __min_cap && !__libcpp_is_constant_evaluated())
     {
         __set_short_size(__sz);
         __p = __get_short_pointer();
@@ -2174,6 +2269,7 @@
     {
         size_type __cap = __recommend(__sz);
         __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __begin_lifetime(__p, __cap + 1);
         __set_long_pointer(__p);
         __set_long_cap(__cap+1);
         __set_long_size(__sz);
@@ -2197,9 +2293,15 @@
 #endif  // _LIBCPP_NO_EXCEPTIONS
 }
 
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17 void basic_string<_CharT, _Traits, _Allocator>::__free_memory_constexpr() {
+  if (__libcpp_is_constant_evaluated() && __get_long_pointer() != nullptr)
+    __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+}
+
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator, class>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
      : __r_(__default_init_tag(), __default_init_tag())
 {
@@ -2211,7 +2313,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator, class>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
                                                         const allocator_type& __a)
     : __r_(__default_init_tag(), __a)
@@ -2225,7 +2327,7 @@
 #ifndef _LIBCPP_CXX03_LANG
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(
     initializer_list<_CharT> __il)
      : __r_(__default_init_tag(), __default_init_tag())
@@ -2237,8 +2339,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
-
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::basic_string(
     initializer_list<_CharT> __il, const _Allocator& __a)
     : __r_(__default_init_tag(), __a)
@@ -2252,29 +2353,34 @@
 #endif // _LIBCPP_CXX03_LANG
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::~basic_string()
 {
 #if _LIBCPP_DEBUG_LEVEL == 2
     __get_db()->__erase_c(this);
 #endif
-    if (__is_long())
-        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+  if (__libcpp_is_constant_evaluated())
+    __free_memory_constexpr();
+  else if (__is_long())
+    __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
     (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
      size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
 {
-    size_type __ms = max_size();
-    if (__delta_cap > __ms - __old_cap - 1)
+    size_type __max_size = max_size();
+    if (__delta_cap > __max_size - __old_cap - 1)
         this->__throw_length_error();
     pointer __old_p = __get_pointer();
-    size_type __cap = __old_cap < __ms / 2 - __alignment ?
+    size_type __cap = __old_cap < __max_size / 2 - __alignment ?
                           __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
-                          __ms - 1;
-    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
+                          __max_size - 1;
+    pointer __p = __alloc_traits::allocate(__alloc(), __cap + 1);
+    __begin_lifetime(__p, __cap + 1);
     __invalidate_all_iterators();
     if (__n_copy != 0)
         traits_type::copy(_VSTD::__to_address(__p),
@@ -2295,6 +2401,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                                                      size_type __n_copy,  size_type __n_del,     size_type __n_add)
@@ -2307,6 +2414,7 @@
                           __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
                           __ms - 1;
     pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
+    __begin_lifetime(__p, __cap + 1);
     __invalidate_all_iterators();
     if (__n_copy != 0)
         traits_type::copy(_VSTD::__to_address(__p),
@@ -2316,7 +2424,7 @@
         traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add,
                           _VSTD::__to_address(__old_p) + __n_copy + __n_del,
                           __sec_cp_sz);
-    if (__old_cap+1 != __min_cap)
+    if (__old_cap+1 != __min_cap || __libcpp_is_constant_evaluated())
         __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
     __set_long_pointer(__p);
     __set_long_cap(__cap+1);
@@ -2326,6 +2434,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <bool __is_short>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
     const value_type* __s, size_type __n) {
@@ -2344,6 +2453,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::__assign_external(
     const value_type* __s, size_type __n) {
@@ -2362,16 +2472,18 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
-    return (__builtin_constant_p(__n) && __n < __min_cap)
+    return (__builtin_constant_p(__n) && __n < __min_cap && !__libcpp_is_constant_evaluated())
                ? __assign_short(__s, __n)
                : __assign_external(__s, __n);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
 {
@@ -2390,6 +2502,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
 {
@@ -2411,6 +2524,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
 {
@@ -2432,7 +2546,7 @@
 #ifndef _LIBCPP_CXX03_LANG
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
     _NOEXCEPT_(__alloc_traits::is_always_equal::value)
@@ -2444,7 +2558,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
 #if _LIBCPP_STD_VER > 14
@@ -2465,12 +2579,17 @@
   }
   __move_assign_alloc(__str);
   __r_.first() = __str.__r_.first();
+  if (__libcpp_is_constant_evaluated())
+      __str.__zero();
+  else
+  {
   __str.__set_short_size(0);
   traits_type::assign(__str.__get_short_pointer()[0], value_type());
+  }
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
     _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value))
@@ -2484,6 +2603,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
      __is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -2498,6 +2618,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -2509,7 +2630,7 @@
     size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ?
         static_cast<size_type>(_VSTD::distance(__first, __last)) : 0;
 
-    if (__string_is_trivial_iterator<_ForwardIterator>::value &&
+    if (__string_is_trivial_iterator<_ForwardIterator>::value && !__libcpp_is_constant_evaluated() &&
         (__cap >= __n || !__addr_in_range(*__first)))
     {
         if (__cap < __n)
@@ -2533,6 +2654,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
 {
@@ -2550,6 +2672,7 @@
     && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
     basic_string<_CharT, _Traits, _Allocator>&
 >
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
 {
     __self_view __sv = __t;
@@ -2567,12 +2690,13 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
     return __builtin_constant_p(*__s)
-               ? (traits_type::length(__s) < __min_cap
+               ? (traits_type::length(__s) < __min_cap && !__libcpp_is_constant_evaluated()
                       ? __assign_short(__s, traits_type::length(__s))
                       : __assign_external(__s, traits_type::length(__s)))
                : __assign_external(__s);
@@ -2580,6 +2704,7 @@
 // append
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
 {
@@ -2603,6 +2728,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
 {
@@ -2639,6 +2765,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
 {
@@ -2677,6 +2804,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -2690,7 +2818,7 @@
     size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
     if (__n)
     {
-        if (__string_is_trivial_iterator<_ForwardIterator>::value &&
+        if (!__libcpp_is_constant_evaluated() && __string_is_trivial_iterator<_ForwardIterator>::value &&
             !__addr_in_range(*__first))
         {
             if (__cap - __sz < __n)
@@ -2711,7 +2839,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
 {
@@ -2719,6 +2847,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
 {
@@ -2730,6 +2859,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
     __enable_if_t
     <
         __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
@@ -2745,6 +2875,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
 {
@@ -2755,38 +2886,50 @@
 // insert
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __count)
 {
-    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
-    size_type __sz = size();
-    if (__pos > __sz)
+    _LIBCPP_ASSERT(__count == 0 || __s != nullptr, "string::insert received nullptr");
+    size_type __size = size();
+    if (__pos > __size)
         this->__throw_out_of_range();
-    size_type __cap = capacity();
-    if (__cap - __sz >= __n)
+    size_type __capacity = capacity();
+
+    if (__libcpp_is_constant_evaluated())
     {
-        if (__n)
+        if (__capacity - __size >= __count)
+            __grow_by_and_replace(__capacity, 0, __size, __pos, 0, __count, __s);
+        else
+            __grow_by_and_replace(__capacity, __size + __count - __capacity, __size, __pos, 0, __count, __s);
+        return *this;
+    }
+
+    if (__capacity - __size >= __count)
+    {
+        if (__count > 0)
         {
-            value_type* __p = _VSTD::__to_address(__get_pointer());
-            size_type __n_move = __sz - __pos;
+            value_type* __begin = _VSTD::__to_address(__get_pointer());
+            size_type __n_move = __size - __pos;
             if (__n_move != 0)
             {
-                if (__p + __pos <= __s && __s < __p + __sz)
-                    __s += __n;
-                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
+                if (__begin + __pos <= __s && __s < __begin + __size)
+                    __s += __count;
+                traits_type::move(__begin + __pos + __count, __begin + __pos, __n_move);
             }
-            traits_type::move(__p + __pos, __s, __n);
-            __sz += __n;
-            __set_size(__sz);
-            traits_type::assign(__p[__sz], value_type());
+            traits_type::move(__begin + __pos, __s, __count);
+            __size += __count;
+            __set_size(__size);
+            traits_type::assign(__begin[__size], value_type());
         }
     }
     else
-        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
+        __grow_by_and_replace(__capacity, __size + __count - __capacity, __size, __pos, 0, __count, __s);
     return *this;
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
 {
@@ -2819,6 +2962,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
    __is_exactly_cpp17_input_iterator<_InputIterator>::value,
@@ -2835,8 +2979,39 @@
     return insert(__pos, __temp.data(), __temp.data() + __temp.size());
 }
 
+template<class _CharT, class _Traits, class _Allocator>
+template<class _ForwardIterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 void
+basic_string<_CharT, _Traits, _Allocator>::__insert_not_in_range(const size_type __ip,
+                                                                 const size_type __n,
+                                                                 _ForwardIterator __first,
+                                                                 _ForwardIterator __last)
+{
+    size_type __sz = size();
+    size_type __cap = capacity();
+    value_type* __p;
+    if (__cap - __sz >= __n)
+    {
+        __p = _VSTD::__to_address(__get_pointer());
+        size_type __n_move = __sz - __ip;
+        if (__n_move != 0)
+            traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
+    }
+    else
+    {
+        __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
+        __p = _VSTD::__to_address(__get_long_pointer());
+    }
+    __sz += __n;
+    __set_size(__sz);
+    traits_type::assign(__p[__sz], value_type());
+    for (__p += __ip; __first != __last; ++__p, (void) ++__first)
+        traits_type::assign(*__p, *__first);
+}
+
 template <class _CharT, class _Traits, class _Allocator>
 template<class _ForwardIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __is_cpp17_forward_iterator<_ForwardIterator>::value,
@@ -2853,41 +3028,21 @@
     size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
     if (__n)
     {
-        if (__string_is_trivial_iterator<_ForwardIterator>::value &&
-            !__addr_in_range(*__first))
-        {
-            size_type __sz = size();
-            size_type __cap = capacity();
-            value_type* __p;
-            if (__cap - __sz >= __n)
-            {
-                __p = _VSTD::__to_address(__get_pointer());
-                size_type __n_move = __sz - __ip;
-                if (__n_move != 0)
-                    traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
-            }
-            else
-            {
-                __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
-                __p = _VSTD::__to_address(__get_long_pointer());
-            }
-            __sz += __n;
-            __set_size(__sz);
-            traits_type::assign(__p[__sz], value_type());
-            for (__p += __ip; __first != __last; ++__p, (void) ++__first)
-                traits_type::assign(*__p, *__first);
-        }
-        else
+        if (!__string_is_trivial_iterator<_ForwardIterator>::value || __libcpp_is_constant_evaluated() ||
+            __addr_in_range(*__first))
         {
             const basic_string __temp(__first, __last, __alloc());
-            return insert(__pos, __temp.data(), __temp.data() + __temp.size());
+            __insert_not_in_range(__ip, __n, __temp.data(), __temp.data() + __temp.size());
         }
+        else
+            __insert_not_in_range(__ip, __n, __first, __last);
+        
     }
     return begin() + __ip;
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
 {
@@ -2895,6 +3050,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
                                                   size_type __pos2, size_type __n)
@@ -2907,6 +3063,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
@@ -2923,6 +3080,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
 {
@@ -2931,6 +3089,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
 {
@@ -2957,7 +3116,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
 {
@@ -2973,7 +3132,21 @@
 
 // replace
 
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
+void
+basic_string<_CharT, _Traits, _Allocator>::__finish_replace(size_type& __sz,
+                                                            size_type& __n1,
+                                                            size_type& __n2,
+                                                            value_type*& __p) {
+  __sz += __n2 - __n1;
+  __set_size(__sz);
+  __invalidate_iterators_past(__sz);
+  traits_type::assign(__p[__sz], value_type());
+}
+
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
@@ -2986,6 +3159,11 @@
     size_type __cap = capacity();
     if (__cap - __sz + __n1 >= __n2)
     {
+        if (__libcpp_is_constant_evaluated()) {
+            __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s);
+            return *this;
+        }
+
         value_type* __p = _VSTD::__to_address(__get_pointer());
         if (__n1 != __n2)
         {
@@ -2996,7 +3174,8 @@
                 {
                     traits_type::move(__p + __pos, __s, __n2);
                     traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
-                    goto __finish;
+                    __finish_replace(__sz, __n1, __n2, __p);
+                    return *this;
                 }
                 if (__p + __pos < __s && __s < __p + __sz)
                 {
@@ -3015,13 +3194,9 @@
             }
         }
         traits_type::move(__p + __pos, __s, __n2);
-__finish:
 // __sz += __n2 - __n1; in this and the below function below can cause unsigned
 // integer overflow, but this is a safe operation, so we disable the check.
-        __sz += __n2 - __n1;
-        __set_size(__sz);
-        __invalidate_iterators_past(__sz);
-        traits_type::assign(__p[__sz], value_type());
+        __finish_replace(__sz, __n1, __n2, __p);
     }
     else
         __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
@@ -3029,6 +3204,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
@@ -3064,6 +3240,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __is_cpp17_input_iterator<_InputIterator>::value,
@@ -3077,7 +3254,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
 {
@@ -3085,6 +3262,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
                                                    size_type __pos2, size_type __n2)
@@ -3097,6 +3275,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
@@ -3113,6 +3292,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
 {
@@ -3121,7 +3301,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
 {
@@ -3130,7 +3310,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
 {
@@ -3138,7 +3318,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
 {
@@ -3146,7 +3326,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
 {
@@ -3158,6 +3338,7 @@
 // 'externally instantiated' erase() implementation, called when __n != npos.
 // Does not check __pos against size()
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
     size_type __pos, size_type __n)
@@ -3178,6 +3359,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
                                                  size_type __n) {
@@ -3191,7 +3373,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
 {
@@ -3209,7 +3391,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
 {
@@ -3226,7 +3408,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::pop_back()
 {
@@ -3248,7 +3430,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
 {
@@ -3266,7 +3448,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
 {
@@ -3284,6 +3466,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
 {
@@ -3306,7 +3489,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
 {
@@ -3319,6 +3502,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity)
 {
@@ -3338,6 +3522,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::shrink_to_fit() _NOEXCEPT
 {
@@ -3348,6 +3533,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target_capacity)
 {
@@ -3356,7 +3542,7 @@
 
     pointer __new_data, __p;
     bool __was_long, __now_long;
-    if (__target_capacity == __min_cap - 1)
+    if (__target_capacity == __min_cap - 1 && !__libcpp_is_constant_evaluated())
     {
         __was_long = true;
         __now_long = false;
@@ -3366,7 +3552,10 @@
     else
     {
         if (__target_capacity > __cap)
+        {
             __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1);
+            __begin_lifetime(__new_data, __target_capacity + 1);
+        }
         else
         {
         #ifndef _LIBCPP_NO_EXCEPTIONS
@@ -3374,6 +3563,7 @@
             {
         #endif // _LIBCPP_NO_EXCEPTIONS
                 __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1);
+                __begin_lifetime(__new_data, __target_capacity + 1);
         #ifndef _LIBCPP_NO_EXCEPTIONS
             }
             catch (...)
@@ -3405,7 +3595,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT
 {
@@ -3414,7 +3604,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
 {
@@ -3423,6 +3613,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
 {
@@ -3432,6 +3623,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
 {
@@ -3441,7 +3633,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::front() _NOEXCEPT
 {
@@ -3450,7 +3642,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::front() const _NOEXCEPT
 {
@@ -3459,7 +3651,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::back() _NOEXCEPT
 {
@@ -3468,7 +3660,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::back() const _NOEXCEPT
 {
@@ -3477,6 +3669,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
 {
@@ -3489,7 +3682,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
 {
@@ -3497,7 +3690,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
 #if _LIBCPP_STD_VER >= 14
@@ -3534,6 +3727,7 @@
 };
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos,
@@ -3545,7 +3739,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
                                                 size_type __pos) const _NOEXCEPT
@@ -3556,6 +3750,7 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3570,7 +3765,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos) const _NOEXCEPT
@@ -3581,6 +3776,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
                                                 size_type __pos) const _NOEXCEPT
@@ -3592,6 +3788,7 @@
 // rfind
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos,
@@ -3603,7 +3800,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
                                                  size_type __pos) const _NOEXCEPT
@@ -3614,6 +3811,7 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3628,7 +3826,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos) const _NOEXCEPT
@@ -3639,6 +3837,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
                                                  size_type __pos) const _NOEXCEPT
@@ -3650,6 +3849,7 @@
 // find_first_of
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos,
@@ -3661,7 +3861,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
                                                          size_type __pos) const _NOEXCEPT
@@ -3672,6 +3872,7 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3686,7 +3887,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos) const _NOEXCEPT
@@ -3697,7 +3898,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
                                                          size_type __pos) const _NOEXCEPT
@@ -3708,6 +3909,7 @@
 // find_last_of
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos,
@@ -3719,7 +3921,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
                                                         size_type __pos) const _NOEXCEPT
@@ -3730,6 +3932,7 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3744,7 +3947,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos) const _NOEXCEPT
@@ -3755,7 +3958,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
                                                         size_type __pos) const _NOEXCEPT
@@ -3766,6 +3969,7 @@
 // find_first_not_of
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos,
@@ -3777,7 +3981,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
                                                              size_type __pos) const _NOEXCEPT
@@ -3788,6 +3992,7 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3802,7 +4007,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos) const _NOEXCEPT
@@ -3813,7 +4018,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
                                                              size_type __pos) const _NOEXCEPT
@@ -3825,6 +4030,7 @@
 // find_last_not_of
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos,
@@ -3836,7 +4042,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
                                                             size_type __pos) const _NOEXCEPT
@@ -3847,6 +4053,7 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3861,7 +4068,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos) const _NOEXCEPT
@@ -3872,7 +4079,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
                                                             size_type __pos) const _NOEXCEPT
@@ -3885,6 +4092,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3907,7 +4115,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
 {
@@ -3915,6 +4123,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
@@ -3939,6 +4148,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
@@ -3953,7 +4163,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
@@ -3964,6 +4174,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Tp>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 __enable_if_t
 <
     __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
@@ -3981,6 +4192,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
@@ -3992,6 +4204,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
 {
@@ -4000,6 +4213,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
@@ -4012,13 +4226,13 @@
 // __invariants
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 basic_string<_CharT, _Traits, _Allocator>::__invariants() const
 {
     if (size() > capacity())
         return false;
-    if (capacity() < __min_cap - 1)
+    if (capacity() < __min_cap - 1 && !__libcpp_is_constant_evaluated())
         return false;
     if (data() == nullptr)
         return false;
@@ -4030,7 +4244,7 @@
 // __clear_and_shrink
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
 {
@@ -4038,16 +4252,21 @@
     if(__is_long())
     {
         __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
-        __set_long_cap(0);
-        __set_short_size(0);
-        traits_type::assign(*__get_short_pointer(), value_type());
+        if (__libcpp_is_constant_evaluated())
+            __zero();
+        else
+        {
+            __set_long_cap(0);
+            __set_short_size(0);
+            traits_type::assign(*__get_short_pointer(), value_type());
+        }
     }
 }
 
 // operator==
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4059,7 +4278,7 @@
 }
 
 template<class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
            const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
@@ -4078,7 +4297,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator==(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4091,7 +4310,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -4104,7 +4323,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4113,7 +4332,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator!=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4122,7 +4341,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -4133,7 +4352,7 @@
 // operator<
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4142,7 +4361,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -4151,7 +4370,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator< (const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4162,7 +4381,7 @@
 // operator>
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4171,7 +4390,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -4180,7 +4399,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator> (const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4191,7 +4410,7 @@
 // operator<=
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4200,7 +4419,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -4209,7 +4428,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator<=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4220,7 +4439,7 @@
 // operator>=
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4229,7 +4448,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -4238,7 +4457,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 bool
 operator>=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -4249,6 +4468,7 @@
 // operator +
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
           const basic_string<_CharT, _Traits, _Allocator>& __rhs)
@@ -4256,53 +4476,61 @@
     basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
+    __r.__free_memory_constexpr();
     __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
     __r.append(__rhs.data(), __rhs_sz);
     return __r;
 }
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 {
     basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
+    __r.__free_memory_constexpr();
     __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
     __r.append(__rhs.data(), __rhs_sz);
     return __r;
 }
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
 {
     basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
+    __r.__free_memory_constexpr();
     __r.__init(&__lhs, 1, 1 + __rhs_sz);
     __r.append(__rhs.data(), __rhs_sz);
     return __r;
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline
+inline _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
 {
     basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
+    __r.__free_memory_constexpr();
     __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
     __r.append(__rhs, __rhs_sz);
     return __r;
 }
 
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
 {
     basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
     typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
+    __r.__free_memory_constexpr();
     __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
     __r.push_back(__rhs);
     return __r;
@@ -4311,7 +4539,7 @@
 #ifndef _LIBCPP_CXX03_LANG
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
 {
@@ -4319,7 +4547,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
 {
@@ -4327,7 +4555,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
 {
@@ -4335,7 +4563,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
 {
@@ -4343,7 +4571,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
 {
@@ -4352,7 +4580,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
 {
@@ -4360,7 +4588,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
 {
@@ -4373,7 +4601,7 @@
 // swap
 
 template<class _CharT, class _Traits, class _Allocator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
      basic_string<_CharT, _Traits, _Allocator>& __rhs)
@@ -4538,14 +4766,14 @@
 {
   inline namespace string_literals
   {
-    inline _LIBCPP_INLINE_VISIBILITY
+    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string<char> operator "" s( const char *__str, size_t __len )
     {
         return basic_string<char> (__str, __len);
     }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-    inline _LIBCPP_INLINE_VISIBILITY
+    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
     {
         return basic_string<wchar_t> (__str, __len);
@@ -4553,20 +4781,20 @@
 #endif
 
 #ifndef _LIBCPP_HAS_NO_CHAR8_T
-    inline _LIBCPP_INLINE_VISIBILITY
+    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT
     {
         return basic_string<char8_t> (__str, __len);
     }
 #endif
 
-    inline _LIBCPP_INLINE_VISIBILITY
+    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
     {
         return basic_string<char16_t> (__str, __len);
     }
 
-    inline _LIBCPP_INLINE_VISIBILITY
+    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
     {
         return basic_string<char32_t> (__str, __len);
diff --git a/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp b/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp
--- a/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp
+++ b/libcxx/test/std/input.output/iostream.format/quoted.manip/quoted_traits.verify.cpp
@@ -23,16 +23,24 @@
 
 template <class charT>
 struct test_traits {
-    typedef charT char_type;
+  typedef charT char_type;
+  typedef int int_type;
+  static inline _LIBCPP_CONSTEXPR_AFTER_CXX14 void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
+    __c1 = __c2;
+  }
+  static inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
+    return std::__libcpp_is_constant_evaluated() ? _VSTD::__assign_constexpr(__s, __n, __a)
+           : __n == 0                            ? __s
+                                                 : (char_type*)_VSTD::memset(__s, to_int_type(__a), __n);
+  }
+  static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT { return int_type((unsigned char)__c); }
 };
 
-void round_trip ( const char *p ) {
-    std::stringstream ss;
-    ss << std::quoted(p);
-    std::basic_string<char, test_traits<char>> s;
-    ss >> std::quoted(s); // expected-error {{invalid operands to binary expression}}
+void round_trip(const char* p) {
+  std::stringstream ss;
+  ss << std::quoted(p);
+  std::basic_string<char, test_traits<char> > s;
+  ss >> std::quoted(s); // expected-error {{invalid operands to binary expression}}
 }
 
-int main(int, char**) {
-    round_trip("Hi Mom");
-}
+int main(int, char**) { round_trip("Hi Mom"); }
diff --git a/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h b/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h
--- a/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h
+++ b/libcxx/test/std/strings/basic.string/cpp17_input_iterator.h
@@ -22,18 +22,18 @@
     typedef It                                                 pointer;
     typedef typename std::iterator_traits<It>::reference       reference;
 
-    cpp17_input_iterator() : it_() {}
-    explicit cpp17_input_iterator(It it) : it_(it) {}
+    TEST_CONSTEXPR_CXX20 cpp17_input_iterator() : it_() {}
+    TEST_CONSTEXPR_CXX20 explicit cpp17_input_iterator(It it) : it_(it) {}
 
-    reference operator*() const {return *it_;}
-    pointer operator->() const {return it_;}
+    TEST_CONSTEXPR_CXX20 reference operator*() const {return *it_;}
+    TEST_CONSTEXPR_CXX20 pointer operator->() const {return it_;}
 
-    cpp17_input_iterator& operator++() {++it_; return *this;}
-    cpp17_input_iterator operator++(int) {cpp17_input_iterator tmp(*this); ++(*this); return tmp;}
+    TEST_CONSTEXPR_CXX20 cpp17_input_iterator& operator++() {++it_; return *this;}
+    TEST_CONSTEXPR_CXX20 cpp17_input_iterator operator++(int) {cpp17_input_iterator tmp(*this); ++(*this); return tmp;}
 
-    friend bool operator==(const cpp17_input_iterator& x, const cpp17_input_iterator& y)
+    TEST_CONSTEXPR_CXX20 friend bool operator==(const cpp17_input_iterator& x, const cpp17_input_iterator& y)
         {return x.it_ == y.it_;}
-    friend bool operator!=(const cpp17_input_iterator& x, const cpp17_input_iterator& y)
+    TEST_CONSTEXPR_CXX20 friend bool operator!=(const cpp17_input_iterator& x, const cpp17_input_iterator& y)
         {return !(x == y);}
 };
 
diff --git a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp
@@ -20,59 +20,72 @@
 #include "test_macros.h"
 
 template <class S>
-void
-test(S s, typename S::size_type pos)
-{
-    const S& cs = s;
-    if (pos < s.size())
-    {
-        assert(s.at(pos) == s[pos]);
-        assert(cs.at(pos) == cs[pos]);
-    }
+TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos) {
+  const S& cs = s;
+  if (pos < s.size()) {
+    assert(s.at(pos) == s[pos]);
+    assert(cs.at(pos) == cs[pos]);
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
-        try
-        {
-            TEST_IGNORE_NODISCARD s.at(pos);
-            assert(false);
-        }
-        catch (std::out_of_range&)
-        {
-            assert(pos >= s.size());
-        }
-        try
-        {
-            TEST_IGNORE_NODISCARD cs.at(pos);
-            assert(false);
-        }
-        catch (std::out_of_range&)
-        {
-            assert(pos >= s.size());
-        }
+  else {
+    try {
+      TEST_IGNORE_NODISCARD s.at(pos);
+      assert(false);
+    } catch (std::out_of_range&) {
+      assert(pos >= s.size());
+    }
+    try {
+      TEST_IGNORE_NODISCARD cs.at(pos);
+      assert(false);
+    } catch (std::out_of_range&) {
+      assert(pos >= s.size());
     }
+  }
 #endif
 }
 
-int main(int, char**)
-{
-    {
+bool test() {
+  {
     typedef std::string S;
     test(S(), 0);
+    test(S("123"), 3);
+  }
+#if TEST_STD_VER >= 11
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
+    test(S(), 0);
+    test(S("123"), 3);
+  }
+#endif
+  return true;
+}
+
+TEST_CONSTEXPR_CXX20
+bool constexpr_test() {
+  {
+    typedef std::string S;
     test(S("123"), 0);
     test(S("123"), 1);
     test(S("123"), 2);
-    test(S("123"), 3);
-    }
+  }
 #if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
-    test(S(), 0);
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
     test(S("123"), 0);
     test(S("123"), 1);
     test(S("123"), 2);
-    test(S("123"), 3);
-    }
+  }
+#endif
+  return true;
+}
+
+int main(int, char**) {
+
+  test();
+  constexpr_test();
+
+#if TEST_STD_VER > 17
+  static_assert(constexpr_test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp
@@ -18,34 +18,40 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    const S& cs = s;
-    ASSERT_SAME_TYPE(decltype( s.back()), typename S::reference);
-    ASSERT_SAME_TYPE(decltype(cs.back()), typename S::const_reference);
-    LIBCPP_ASSERT_NOEXCEPT(    s.back());
-    LIBCPP_ASSERT_NOEXCEPT(   cs.back());
-    assert(&cs.back() == &cs[cs.size()-1]);
-    assert(&s.back() == &s[cs.size()-1]);
-    s.back() = typename S::value_type('z');
-    assert(s.back() == typename S::value_type('z'));
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  const S& cs = s;
+  ASSERT_SAME_TYPE(decltype(s.back()), typename S::reference);
+  ASSERT_SAME_TYPE(decltype(cs.back()), typename S::const_reference);
+  LIBCPP_ASSERT_NOEXCEPT(s.back());
+  LIBCPP_ASSERT_NOEXCEPT(cs.back());
+  assert(&cs.back() == &cs[cs.size() - 1]);
+  assert(&s.back() == &s[cs.size() - 1]);
+  s.back() = typename S::value_type('z');
+  assert(s.back() == typename S::value_type('z'));
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S("1"));
     test(S("1234567890123456789012345678901234567890"));
-    }
+  }
 #if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
     test(S("1"));
     test(S("1234567890123456789012345678901234567890"));
-    }
+  }
+#endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
-    return 0;
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp
@@ -18,34 +18,40 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    const S& cs = s;
-    ASSERT_SAME_TYPE(decltype( s.front()), typename S::reference);
-    ASSERT_SAME_TYPE(decltype(cs.front()), typename S::const_reference);
-    LIBCPP_ASSERT_NOEXCEPT(    s.front());
-    LIBCPP_ASSERT_NOEXCEPT(   cs.front());
-    assert(&cs.front() == &cs[0]);
-    assert(&s.front() == &s[0]);
-    s.front() = typename S::value_type('z');
-    assert(s.front() == typename S::value_type('z'));
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  const S& cs = s;
+  ASSERT_SAME_TYPE(decltype(s.front()), typename S::reference);
+  ASSERT_SAME_TYPE(decltype(cs.front()), typename S::const_reference);
+  LIBCPP_ASSERT_NOEXCEPT(s.front());
+  LIBCPP_ASSERT_NOEXCEPT(cs.front());
+  assert(&cs.front() == &cs[0]);
+  assert(&s.front() == &s[0]);
+  s.front() = typename S::value_type('z');
+  assert(s.front() == typename S::value_type('z'));
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S("1"));
     test(S("1234567890123456789012345678901234567890"));
-    }
+  }
 #if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
     test(S("1"));
     test(S("1234567890123456789012345678901234567890"));
-    }
+  }
+#endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
-    return 0;
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp
@@ -17,44 +17,50 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     S s("0123456789");
     const S& cs = s;
-    ASSERT_SAME_TYPE(decltype( s[0]), typename S::reference);
+    ASSERT_SAME_TYPE(decltype(s[0]), typename S::reference);
     ASSERT_SAME_TYPE(decltype(cs[0]), typename S::const_reference);
-    LIBCPP_ASSERT_NOEXCEPT(    s[0]);
-    LIBCPP_ASSERT_NOEXCEPT(   cs[0]);
-    for (S::size_type i = 0; i < cs.size(); ++i)
-    {
-        assert(s[i] == static_cast<char>('0' + i));
-        assert(cs[i] == s[i]);
+    LIBCPP_ASSERT_NOEXCEPT(s[0]);
+    LIBCPP_ASSERT_NOEXCEPT(cs[0]);
+    for (S::size_type i = 0; i < cs.size(); ++i) {
+      assert(s[i] == static_cast<char>('0' + i));
+      assert(cs[i] == s[i]);
     }
     assert(cs[cs.size()] == '\0');
     const S s2 = S();
     assert(s2[0] == '\0');
-    }
+  }
 #if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
     S s("0123456789");
     const S& cs = s;
-    ASSERT_SAME_TYPE(decltype( s[0]), typename S::reference);
+    ASSERT_SAME_TYPE(decltype(s[0]), typename S::reference);
     ASSERT_SAME_TYPE(decltype(cs[0]), typename S::const_reference);
-    LIBCPP_ASSERT_NOEXCEPT(    s[0]);
-    LIBCPP_ASSERT_NOEXCEPT(   cs[0]);
-    for (S::size_type i = 0; i < cs.size(); ++i)
-    {
-        assert(s[i] == static_cast<char>('0' + i));
-        assert(cs[i] == s[i]);
+    LIBCPP_ASSERT_NOEXCEPT(s[0]);
+    LIBCPP_ASSERT_NOEXCEPT(cs[0]);
+    for (S::size_type i = 0; i < cs.size(); ++i) {
+      assert(s[i] == static_cast<char>('0' + i));
+      assert(cs[i] == s[i]);
     }
     assert(cs[cs.size()] == '\0');
     const S s2 = S();
     assert(s2[0] == '\0');
-    }
+  }
+#endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
-    return 0;
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
@@ -18,49 +18,54 @@
 
 #include "test_macros.h"
 
-test_allocator_statistics alloc_stats;
-
 template <class S>
-void
-test(S s)
-{
-    alloc_stats.throw_after = 0;
+TEST_CONSTEXPR_CXX20 void test(S s, test_allocator_statistics& alloc_stats) {
+  alloc_stats.throw_after = 0;
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    try
+  try
 #endif
-    {
-        while (s.size() < s.capacity())
-            s.push_back(typename S::value_type());
-        assert(s.size() == s.capacity());
-    }
+  {
+    while (s.size() < s.capacity())
+      s.push_back(typename S::value_type());
+    assert(s.size() == s.capacity());
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    catch (...)
-    {
-        assert(false);
-    }
+  catch (...) {
+    assert(false);
+  }
 #endif
     alloc_stats.throw_after = INT_MAX;
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
+    test_allocator_statistics alloc_stats;
     typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > S;
     S s((test_allocator<char>(&alloc_stats)));
-    test(s);
+    test(s, alloc_stats);
     s.assign(10, 'a');
     s.erase(5);
-    test(s);
+    test(s, alloc_stats);
     s.assign(100, 'a');
     s.erase(50);
-    test(s);
-    }
+    test(s, alloc_stats);
+  }
 #if TEST_STD_VER >= 11
-    {
+  {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     S s;
     assert(s.capacity() > 0);
-    }
+  }
+#endif
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp
@@ -17,16 +17,14 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    s.clear();
-    assert(s.size() == 0);
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  s.clear();
+  assert(s.size() == 0);
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     S s;
     test(s);
@@ -55,5 +53,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp
@@ -17,28 +17,34 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s)
-{
-    ASSERT_NOEXCEPT(s.empty());
-    assert(s.empty() == (s.size() == 0));
+TEST_CONSTEXPR_CXX20 void test(const S& s) {
+  ASSERT_NOEXCEPT(s.empty());
+  assert(s.empty() == (s.size() == 0));
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
     test(S("12345678901234567890123456789012345678901234567890"));
-    }
+  }
 #if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
     test(S());
     test(S("123"));
     test(S("12345678901234567890123456789012345678901234567890"));
-    }
+  }
+#endif
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp
@@ -17,15 +17,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s)
-{
-    assert(s.length() == s.size());
+TEST_CONSTEXPR_CXX20 void test(const S& s) {
+  assert(s.length() == s.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -40,5 +38,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
@@ -23,82 +23,78 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(typename S::size_type min_cap, typename S::size_type erased_index, typename S::size_type res_arg)
-{
-    S s(min_cap, 'a');
-    s.erase(erased_index);
-    assert(s.size() == erased_index);
-    assert(s.capacity() >= min_cap); // Check that we really have at least this capacity.
+void test(typename S::size_type min_cap, typename S::size_type erased_index, typename S::size_type res_arg) {
+  S s(min_cap, 'a');
+  s.erase(erased_index);
+  assert(s.size() == erased_index);
+  assert(s.capacity() >= min_cap); // Check that we really have at least this capacity.
 
 #if TEST_STD_VER > 17
-    typename S::size_type old_cap = s.capacity();
+  typename S::size_type old_cap = s.capacity();
 #endif
-    S s0 = s;
-    if (res_arg <= s.max_size())
-    {
-        s.reserve(res_arg);
-        LIBCPP_ASSERT(s.__invariants());
-        assert(s == s0);
-        assert(s.capacity() >= res_arg);
-        assert(s.capacity() >= s.size());
+  S s0 = s;
+  if (res_arg <= s.max_size()) {
+    s.reserve(res_arg);
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == s0);
+    assert(s.capacity() >= res_arg);
+    assert(s.capacity() >= s.size());
 #if TEST_STD_VER > 17
-        assert(s.capacity() >= old_cap); // reserve never shrinks as of P0966 (C++20)
+    assert(s.capacity() >= old_cap); // reserve never shrinks as of P0966 (C++20)
 #endif
-    }
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
-        try
-        {
-            s.reserve(res_arg);
-            LIBCPP_ASSERT(s.__invariants());
-            assert(false);
-        }
-        catch (std::length_error&)
-        {
-            assert(res_arg > s.max_size());
-        }
+  else {
+    try {
+      s.reserve(res_arg);
+      LIBCPP_ASSERT(s.__invariants());
+      assert(false);
+    } catch (std::length_error&) {
+      assert(res_arg > s.max_size());
     }
+  }
 #endif
 }
 
-int main(int, char**)
-{
-    {
+void test() {
+  {
     typedef std::string S;
     {
-    test<S>(0, 0, 5);
-    test<S>(0, 0, 10);
-    test<S>(0, 0, 50);
+      test<S>(0, 0, 5);
+      test<S>(0, 0, 10);
+      test<S>(0, 0, 50);
     }
     {
-    test<S>(100, 50, 5);
-    test<S>(100, 50, 10);
-    test<S>(100, 50, 50);
-    test<S>(100, 50, 100);
-    test<S>(100, 50, 1000);
-    test<S>(100, 50, S::npos);
-    }
+      test<S>(100, 50, 5);
+      test<S>(100, 50, 10);
+      test<S>(100, 50, 50);
+      test<S>(100, 50, 100);
+      test<S>(100, 50, 1000);
+      test<S>(100, 50, S::npos);
     }
+  }
 #if TEST_STD_VER >= 11
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
     {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
-    {
-    test<S>(0, 0, 5);
-    test<S>(0, 0, 10);
-    test<S>(0, 0, 50);
+      test<S>(0, 0, 5);
+      test<S>(0, 0, 10);
+      test<S>(0, 0, 50);
     }
     {
-    test<S>(100, 50, 5);
-    test<S>(100, 50, 10);
-    test<S>(100, 50, 50);
-    test<S>(100, 50, 100);
-    test<S>(100, 50, 1000);
-    test<S>(100, 50, S::npos);
-    }
+      test<S>(100, 50, 5);
+      test<S>(100, 50, 10);
+      test<S>(100, 50, 50);
+      test<S>(100, 50, 100);
+      test<S>(100, 50, 1000);
+      test<S>(100, 50, S::npos);
     }
+  }
 #endif
+}
+
+int main(int, char**) {
+  test();
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp
@@ -18,18 +18,14 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s, typename S::size_type n, S expected)
-{
-    if (n <= s.max_size())
-    {
-        s.resize(n);
-        LIBCPP_ASSERT(s.__invariants());
-        assert(s == expected);
-    }
+TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type n, S expected) {
+  if (n <= s.max_size()) {
+    s.resize(n);
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == expected);
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
+  else {
         try
         {
             s.resize(n);
@@ -43,9 +39,24 @@
 #endif
 }
 
-int main(int, char**)
-{
-    {
+bool test() {
+  {
+    typedef std::string S;
+    test(S(), S::npos, S("not going to happen"));
+  }
+#if TEST_STD_VER >= 11
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
+    test(S(), S::npos, S("not going to happen"));
+  }
+#endif
+
+  return true;
+}
+
+TEST_CONSTEXPR_CXX20
+bool constexpr_test() {
+  {
     typedef std::string S;
     test(S(), 0, S());
     test(S(), 1, S(1, '\0'));
@@ -62,7 +73,6 @@
          S("12345678901234567890123456789012345678901234567890"));
     test(S("12345678901234567890123456789012345678901234567890"), 60,
          S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60));
-    test(S(), S::npos, S("not going to happen"));
     }
 #if TEST_STD_VER >= 11
     {
@@ -82,9 +92,20 @@
          S("12345678901234567890123456789012345678901234567890"));
     test(S("12345678901234567890123456789012345678901234567890"), 60,
          S("12345678901234567890123456789012345678901234567890\0\0\0\0\0\0\0\0\0\0", 60));
-    test(S(), S::npos, S("not going to happen"));
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+
+  test();
+  constexpr_test();
+
+#if TEST_STD_VER > 17
+  static_assert(constexpr_test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp
@@ -18,18 +18,14 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s, typename S::size_type n, typename S::value_type c, S expected)
-{
-    if (n <= s.max_size())
-    {
-        s.resize(n, c);
-        LIBCPP_ASSERT(s.__invariants());
-        assert(s == expected);
-    }
+TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type n, typename S::value_type c, S expected) {
+  if (n <= s.max_size()) {
+    s.resize(n, c);
+    LIBCPP_ASSERT(s.__invariants());
+    assert(s == expected);
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
+  else {
         try
         {
             s.resize(n, c);
@@ -43,9 +39,24 @@
 #endif
 }
 
-int main(int, char**)
-{
-    {
+bool test() {
+  {
+    typedef std::string S;
+    test(S(), S::npos, 'a', S("not going to happen"));
+  }
+#if TEST_STD_VER >= 11
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
+    test(S(), S::npos, 'a', S("not going to happen"));
+  }
+#endif
+
+  return true;
+}
+
+TEST_CONSTEXPR_CXX20
+bool constexpr_test() {
+  {
     typedef std::string S;
     test(S(), 0, 'a', S());
     test(S(), 1, 'a', S("a"));
@@ -62,7 +73,6 @@
          S("12345678901234567890123456789012345678901234567890"));
     test(S("12345678901234567890123456789012345678901234567890"), 60, 'a',
          S("12345678901234567890123456789012345678901234567890aaaaaaaaaa"));
-    test(S(), S::npos, 'a', S("not going to happen"));
     }
 #if TEST_STD_VER >= 11
     {
@@ -82,9 +92,20 @@
          S("12345678901234567890123456789012345678901234567890"));
     test(S("12345678901234567890123456789012345678901234567890"), 60, 'a',
          S("12345678901234567890123456789012345678901234567890aaaaaaaaaa"));
-    test(S(), S::npos, 'a', S("not going to happen"));
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+
+  test();
+  constexpr_test();
+
+#if TEST_STD_VER > 17
+  static_assert(constexpr_test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
@@ -17,21 +17,19 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    typename S::size_type old_cap = s.capacity();
-    S s0 = s;
-    s.shrink_to_fit();
-    LIBCPP_ASSERT(s.__invariants());
-    assert(s == s0);
-    assert(s.capacity() <= old_cap);
-    assert(s.capacity() >= s.size());
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  typename S::size_type old_cap = s.capacity();
+  S s0 = s;
+  s.shrink_to_fit();
+  LIBCPP_ASSERT(s.__invariants());
+  assert(s == s0);
+  assert(s.capacity() <= old_cap);
+  assert(s.capacity() >= s.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     S s;
     test(s);
@@ -60,5 +58,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp
@@ -17,15 +17,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s, typename S::size_type c)
-{
-    assert(s.size() == c);
+TEST_CONSTEXPR_CXX20 void test(const S& s, typename S::size_type c) {
+  assert(s.size() == c);
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S(), 0);
     test(S("123"), 3);
@@ -40,5 +38,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp
@@ -25,26 +25,22 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
-test(SV sv, std::size_t pos, std::size_t n)
-{
-    typedef typename S::traits_type T;
-    typedef typename S::allocator_type A;
-    typedef typename S::size_type Size;
-    if (pos <= sv.size())
-    {
-        S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
-        LIBCPP_ASSERT(s2.__invariants());
-        assert(pos <= sv.size());
-        std::size_t rlen = std::min(sv.size() - pos, n);
-        assert(s2.size() == rlen);
-        assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
-        assert(s2.get_allocator() == A());
-        assert(s2.capacity() >= s2.size());
-    }
+TEST_CONSTEXPR_CXX20 void test(SV sv, std::size_t pos, std::size_t n) {
+  typedef typename S::traits_type T;
+  typedef typename S::allocator_type A;
+  typedef typename S::size_type Size;
+  if (pos <= sv.size()) {
+    S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
+    LIBCPP_ASSERT(s2.__invariants());
+    assert(pos <= sv.size());
+    std::size_t rlen = std::min(sv.size() - pos, n);
+    assert(s2.size() == rlen);
+    assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
+    assert(s2.get_allocator() == A());
+    assert(s2.capacity() >= s2.size());
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
+  else if (!TEST_IS_CONSTANT_EVALUATED) {
         try
         {
             S s2(sv, static_cast<Size>(pos), static_cast<Size>(n));
@@ -54,30 +50,26 @@
         {
             assert(pos > sv.size());
         }
-    }
+  }
 #endif
 }
 
 template <class S, class SV>
-void
-test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a)
-{
-    typedef typename S::traits_type T;
-    typedef typename S::size_type Size;
-    if (pos <= sv.size())
-    {
-        S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
-        LIBCPP_ASSERT(s2.__invariants());
-        assert(pos <= sv.size());
-        std::size_t rlen = std::min(sv.size() - pos, n);
-        assert(s2.size() == rlen);
-        assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
-        assert(s2.get_allocator() == a);
-        assert(s2.capacity() >= s2.size());
-    }
+TEST_CONSTEXPR_CXX20 void test(SV sv, std::size_t pos, std::size_t n, const typename S::allocator_type& a) {
+  typedef typename S::traits_type T;
+  typedef typename S::size_type Size;
+  if (pos <= sv.size()) {
+    S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
+    LIBCPP_ASSERT(s2.__invariants());
+    assert(pos <= sv.size());
+    std::size_t rlen = std::min(sv.size() - pos, n);
+    assert(s2.size() == rlen);
+    assert(T::compare(s2.data(), sv.data() + pos, rlen) == 0);
+    assert(s2.get_allocator() == a);
+    assert(s2.capacity() >= s2.size());
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
+  else if (!TEST_IS_CONSTANT_EVALUATED) {
         try
         {
             S s2(sv, static_cast<Size>(pos), static_cast<Size>(n), a);
@@ -87,14 +79,13 @@
         {
             assert(pos > sv.size());
         }
-    }
+  }
 #endif
 }
 
-int main(int, char**)
-{
-
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
     typedef std::basic_string_view<char, std::char_traits<char> > SV;
     typedef std::basic_string     <char, std::char_traits<char>, A> S;
@@ -184,5 +175,14 @@
     assert(s7 == "AB");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp
@@ -18,10 +18,8 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test()
-{
-    {
+TEST_CONSTEXPR_CXX20 void test() {
+  {
 #if TEST_STD_VER > 14
     static_assert((noexcept(S{})), "" );
 #elif TEST_STD_VER >= 11
@@ -52,11 +50,9 @@
 #if TEST_STD_VER >= 11
 
 template <class S>
-void
-test2()
-{
-    {
-#if TEST_STD_VER > 14
+TEST_CONSTEXPR_CXX20 void test2() {
+  {
+#  if TEST_STD_VER > 14
     static_assert((noexcept(S{})), "" );
 #elif TEST_STD_VER >= 11
     static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" );
@@ -85,13 +81,22 @@
 
 #endif
 
-int main(int, char**)
-{
-    test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
+TEST_CONSTEXPR_CXX20
+bool test() {
+  test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
 #if TEST_STD_VER >= 11
     test2<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
     test2<std::basic_string<char, std::char_traits<char>, explicit_allocator<char> > >();
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/brace_assignment.pass.cpp
@@ -18,8 +18,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20
+bool test() {
   // Test that assignment from {} and {ptr, len} are allowed and are not
   // ambiguous.
   {
@@ -33,5 +33,14 @@
     assert(s == "ab");
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp
@@ -17,20 +17,18 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s1, typename S::value_type s2)
-{
-    typedef typename S::traits_type T;
-    s1 = s2;
-    LIBCPP_ASSERT(s1.__invariants());
-    assert(s1.size() == 1);
-    assert(T::eq(s1[0], s2));
-    assert(s1.capacity() >= s1.size());
+TEST_CONSTEXPR_CXX20 void test(S s1, typename S::value_type s2) {
+  typedef typename S::traits_type T;
+  s1 = s2;
+  LIBCPP_ASSERT(s1.__invariants());
+  assert(s1.size() == 1);
+  assert(T::eq(s1[0], s2));
+  assert(s1.capacity() >= s1.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S(), 'a');
     test(S("1"), 'a');
@@ -47,5 +45,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp
@@ -18,19 +18,17 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s1)
-{
-    S s2 = s1;
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2 == s1);
-    assert(s2.capacity() >= s2.size());
-    assert(s2.get_allocator() == s1.get_allocator());
+TEST_CONSTEXPR_CXX20 void test(S s1) {
+  S s2 = s1;
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2 == s1);
+  assert(s2.capacity() >= s2.size());
+  assert(s2.get_allocator() == s1.get_allocator());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
     test(S(A(3)));
@@ -47,5 +45,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp
@@ -21,20 +21,29 @@
 struct alloc_imp {
     bool active;
 
+    TEST_CONSTEXPR_CXX20
     alloc_imp() : active(true) {}
 
     template <class T>
-    T* allocate(std::size_t n)
-    {
-        if (active)
-            return static_cast<T*>(std::malloc(n * sizeof(T)));
-        else
-            throw std::bad_alloc();
+    TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) {
+      if (active) {
+        if (TEST_IS_CONSTANT_EVALUATED)
+          return std::allocator<T>().allocate(n);
+        return static_cast<T*>(std::malloc(n * sizeof(T)));
+      } else
+        throw std::bad_alloc();
     }
 
     template <class T>
-    void deallocate(T* p, std::size_t) { std::free(p); }
+    TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t s) {
+      if (TEST_IS_CONSTANT_EVALUATED)
+        std::allocator<T>().deallocate(p, s);
+      else
+        std::free(p);
+    }
+    TEST_CONSTEXPR_CXX20
     void activate  ()                  { active = true; }
+    TEST_CONSTEXPR_CXX20
     void deactivate()                  { active = false; }
 };
 
@@ -45,69 +54,51 @@
 
     alloc_imp *imp;
 
+    TEST_CONSTEXPR_CXX20
     poca_alloc(alloc_imp *imp_) : imp (imp_) {}
 
     template <class U>
     poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {}
 
+    TEST_CONSTEXPR_CXX20
     T*   allocate  (std::size_t n)       { return imp->allocate<T>(n);}
+    TEST_CONSTEXPR_CXX20
     void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); }
 };
 
 template <typename T, typename U>
-bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
-{
-    return lhs.imp == rhs.imp;
+TEST_CONSTEXPR_CXX20 bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) {
+  return lhs.imp == rhs.imp;
 }
 
 template <typename T, typename U>
-bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
-{
-    return lhs.imp != rhs.imp;
+TEST_CONSTEXPR_CXX20 bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) {
+  return lhs.imp != rhs.imp;
 }
 
 template <class S>
-void test_assign(S &s1, const S& s2)
-{
-    try { s1 = s2; }
-    catch ( std::bad_alloc &) { return; }
-    assert(false);
+TEST_CONSTEXPR_CXX20 void test_assign(S& s1, const S& s2) {
+  try {
+    s1 = s2;
+  } catch (std::bad_alloc&) {
+    return;
+  }
+  assert(false);
 }
 #endif
 
-
-
 template <class S>
-void
-test(S s1, const typename S::allocator_type& a)
-{
-    S s2(s1, a);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2 == s1);
-    assert(s2.capacity() >= s2.size());
-    assert(s2.get_allocator() == a);
+TEST_CONSTEXPR_CXX20 void test(S s1, const typename S::allocator_type& a) {
+  S s2(s1, a);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2 == s1);
+  assert(s2.capacity() >= s2.size());
+  assert(s2.get_allocator() == a);
 }
 
-int main(int, char**)
-{
-    {
-    typedef test_allocator<char> A;
-    typedef std::basic_string<char, std::char_traits<char>, A> S;
-    test(S(), A(3));
-    test(S("1"), A(5));
-    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
-    }
-#if TEST_STD_VER >= 11
-    {
-    typedef min_allocator<char> A;
-    typedef std::basic_string<char, std::char_traits<char>, A> S;
-    test(S(), A());
-    test(S("1"), A());
-    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
-    }
-
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    {
+bool test() {
+#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
+  {
     typedef poca_alloc<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
     const char * p1 = "This is my first string";
@@ -127,6 +118,40 @@
     assert(s2 == p2);
     }
 #endif
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20
+bool constexpr_test() {
+  {
+    typedef test_allocator<char> A;
+    typedef std::basic_string<char, std::char_traits<char>, A> S;
+    test(S(), A(3));
+    test(S("1"), A(5));
+    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
+  }
+#if TEST_STD_VER >= 11
+  {
+    typedef min_allocator<char> A;
+    typedef std::basic_string<char, std::char_traits<char>, A> S;
+    test(S(), A());
+    test(S("1"), A());
+    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
+  }
+
+#endif
+
+  return true;
+}
+
+int main(int, char**) {
+
+  test();
+  constexpr_test();
+
+#if TEST_STD_VER > 17
+  static_assert(constexpr_test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp
@@ -18,18 +18,16 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s1, const S& s2)
-{
-    s1 = s2;
-    LIBCPP_ASSERT(s1.__invariants());
-    assert(s1 == s2);
-    assert(s1.capacity() >= s1.size());
+TEST_CONSTEXPR_CXX20 void test(S s1, const S& s2) {
+  s1 = s2;
+  LIBCPP_ASSERT(s1.__invariants());
+  assert(s1 == s2);
+  assert(s1.capacity() >= s1.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S(), S());
     test(S("1"), S());
@@ -46,7 +44,7 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890"
            "1234567890123456789012345678901234567890123456789012345678901234567890"),
          S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"));
-    }
+  }
 #if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
@@ -77,5 +75,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp
@@ -19,31 +19,38 @@
 #include "test_allocator.h"
 #include "min_allocator.h"
 
-int main(int, char**)
-{
-    {
-        std::string s = {'a', 'b', 'c'};
-        assert(s == "abc");
-    }
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
+    std::string s = {'a', 'b', 'c'};
+    assert(s == "abc");
+  }
 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-    {
-        std::wstring s;
-        s = {L'a', L'b', L'c'};
-        assert(s == L"abc");
-    }
+  {
+    std::wstring s;
+    s = {L'a', L'b', L'c'};
+    assert(s == L"abc");
+  }
 #endif
-    {
-        typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
-        S s = {'a', 'b', 'c'};
-        assert(s == "abc");
-    }
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-    {
-        typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, min_allocator<wchar_t>> S;
-        S s;
-        s = {L'a', L'b', L'c'};
-        assert(s == L"abc");
-    }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
+    S s = {'a', 'b', 'c'};
+    assert(s == "abc");
+  }
+  {
+    typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, min_allocator<wchar_t> > S;
+    S s;
+    s = {L'a', L'b', L'c'};
+    assert(s == L"abc");
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp
@@ -18,19 +18,28 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
-{
-    {
-        std::string s;
-        s = {'a', 'b', 'c'};
-        assert(s == "abc");
-    }
-    {
-        typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
-        S s;
-        s = {'a', 'b', 'c'};
-        assert(s == "abc");
-    }
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
+    std::string s;
+    s = {'a', 'b', 'c'};
+    assert(s == "abc");
+  }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char> > S;
+    S s;
+    s = {'a', 'b', 'c'};
+    assert(s == "abc");
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp
@@ -24,41 +24,37 @@
 #include "min_allocator.h"
 
 template <class It>
-void
-test(It first, It last)
-{
-    typedef typename std::iterator_traits<It>::value_type charT;
-    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
-    typedef typename S::allocator_type A;
-    S s2(first, last);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == static_cast<std::size_t>(std::distance(first, last)));
-    unsigned i = 0;
-    for (It it = first; it != last; ++it, ++i)
-        assert(s2[i] == *it);
-    assert(s2.get_allocator() == A());
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(It first, It last) {
+  typedef typename std::iterator_traits<It>::value_type charT;
+  typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
+  typedef typename S::allocator_type A;
+  S s2(first, last);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == static_cast<std::size_t>(std::distance(first, last)));
+  unsigned i = 0;
+  for (It it = first; it != last; ++it, ++i)
+    assert(s2[i] == *it);
+  assert(s2.get_allocator() == A());
+  assert(s2.capacity() >= s2.size());
 }
 
 template <class It, class A>
-void
-test(It first, It last, const A& a)
-{
-    typedef typename std::iterator_traits<It>::value_type charT;
-    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
-    S s2(first, last, a);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == static_cast<std::size_t>(std::distance(first, last)));
-    unsigned i = 0;
-    for (It it = first; it != last; ++it, ++i)
-        assert(s2[i] == *it);
-    assert(s2.get_allocator() == a);
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(It first, It last, const A& a) {
+  typedef typename std::iterator_traits<It>::value_type charT;
+  typedef std::basic_string<charT, std::char_traits<charT>, A> S;
+  S s2(first, last, a);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == static_cast<std::size_t>(std::distance(first, last)));
+  unsigned i = 0;
+  for (It it = first; it != last; ++it, ++i)
+    assert(s2[i] == *it);
+  assert(s2.get_allocator() == a);
+  assert(s2.capacity() >= s2.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
     const char* s = "12345678901234567890123456789012345678901234567890";
 
@@ -125,6 +121,14 @@
                                   std::allocator<char> >::value),
           "");
     }
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp
@@ -20,27 +20,28 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s0)
-{
-    S s1 = s0;
-    S s2 = std::move(s0);
-    LIBCPP_ASSERT(s2.__invariants());
+TEST_CONSTEXPR_CXX20 void test(S s0) {
+  S s1 = s0;
+  S s2 = std::move(s0);
+  LIBCPP_ASSERT(s2.__invariants());
+  if (TEST_IS_CONSTANT_EVALUATED)
+    LIBCPP_ASSERT(!s0.__invariants());
+  else
     LIBCPP_ASSERT(s0.__invariants());
-    assert(s2 == s1);
-    assert(s2.capacity() >= s2.size());
-    assert(s2.get_allocator() == s1.get_allocator());
+  assert(s2 == s1);
+  assert(s2.capacity() >= s2.size());
+  assert(s2.get_allocator() == s1.get_allocator());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
     test(S(A(3)));
     test(S("1", A(5)));
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)));
-    }
+  }
     {
     typedef min_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
@@ -49,5 +50,14 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()));
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
@@ -20,22 +20,20 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s0, const typename S::allocator_type& a)
-{
-    S s1 = s0;
-    S s2(std::move(s0), a);
-    LIBCPP_ASSERT(s2.__invariants());
+TEST_CONSTEXPR_CXX20 void test(S s0, const typename S::allocator_type& a) {
+  S s1 = s0;
+  S s2(std::move(s0), a);
+  LIBCPP_ASSERT(s2.__invariants());
+  if (!TEST_IS_CONSTANT_EVALUATED)
     LIBCPP_ASSERT(s0.__invariants());
-    assert(s2 == s1);
-    assert(s2.capacity() >= s2.size());
-    assert(s2.get_allocator() == a);
+  assert(s2 == s1);
+  assert(s2.capacity() >= s2.size());
+  assert(s2.get_allocator() == a);
 }
 
-int main(int, char**)
-{
-    test_allocator_statistics alloc_stats;
-    {
+TEST_CONSTEXPR_CXX20 bool test() {
+  test_allocator_statistics alloc_stats;
+  {
     typedef test_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
 #if TEST_STD_VER > 14
@@ -74,5 +72,14 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp
@@ -21,20 +21,21 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s1, S s2)
-{
-    S s0 = s2;
-    s1 = std::move(s2);
-    LIBCPP_ASSERT(s1.__invariants());
+TEST_CONSTEXPR_CXX20 void test(S s1, S s2) {
+  S s0 = s2;
+  s1 = std::move(s2);
+  LIBCPP_ASSERT(s1.__invariants());
+  if (TEST_IS_CONSTANT_EVALUATED)
+    LIBCPP_ASSERT(!s2.__invariants());
+  else
     LIBCPP_ASSERT(s2.__invariants());
-    assert(s1 == s0);
-    assert(s1.capacity() >= s1.size());
+  assert(s1 == s0);
+  assert(s1.capacity() >= s1.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S(), S());
     test(S("1"), S());
@@ -51,7 +52,7 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890"
            "1234567890123456789012345678901234567890123456789012345678901234567890"),
          S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"));
-    }
+  }
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test(S(), S());
@@ -71,5 +72,14 @@
          S("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"));
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp
@@ -21,39 +21,35 @@
 #include "min_allocator.h"
 
 template <class charT>
-void
-test(const charT* s)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
-    typedef typename S::traits_type T;
-    typedef typename S::allocator_type A;
-    std::size_t n = T::length(s);
-    S s2(s);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == n);
-    assert(T::compare(s2.data(), s, n) == 0);
-    assert(s2.get_allocator() == A());
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(const charT* s) {
+  typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
+  typedef typename S::traits_type T;
+  typedef typename S::allocator_type A;
+  std::size_t n = T::length(s);
+  S s2(s);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == n);
+  assert(T::compare(s2.data(), s, n) == 0);
+  assert(s2.get_allocator() == A());
+  assert(s2.capacity() >= s2.size());
 }
 
 template <class charT, class A>
-void
-test(const charT* s, const A& a)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
-    typedef typename S::traits_type T;
-    std::size_t n = T::length(s);
-    S s2(s, a);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == n);
-    assert(T::compare(s2.data(), s, n) == 0);
-    assert(s2.get_allocator() == a);
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(const charT* s, const A& a) {
+  typedef std::basic_string<charT, std::char_traits<charT>, A> S;
+  typedef typename S::traits_type T;
+  std::size_t n = T::length(s);
+  S s2(s, a);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == n);
+  assert(T::compare(s2.data(), s, n) == 0);
+  assert(s2.get_allocator() == a);
+  assert(s2.capacity() >= s2.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
 
     test("");
@@ -86,5 +82,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp
@@ -18,20 +18,18 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s1, const typename S::value_type* s2)
-{
-    typedef typename S::traits_type T;
-    s1 = s2;
-    LIBCPP_ASSERT(s1.__invariants());
-    assert(s1.size() == T::length(s2));
-    assert(T::compare(s1.data(), s2, s1.size()) == 0);
-    assert(s1.capacity() >= s1.size());
+TEST_CONSTEXPR_CXX20 void test(S s1, const typename S::value_type* s2) {
+  typedef typename S::traits_type T;
+  s1 = s2;
+  LIBCPP_ASSERT(s1.__invariants());
+  assert(s1.size() == T::length(s2));
+  assert(T::compare(s1.data(), s2, s1.size()) == 0);
+  assert(s1.capacity() >= s1.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S(), "");
     test(S("1"), "");
@@ -48,7 +46,7 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890"
            "1234567890123456789012345678901234567890123456789012345678901234567890"),
          "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
-    }
+  }
 #if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
@@ -70,5 +68,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp
@@ -20,37 +20,33 @@
 #include "min_allocator.h"
 
 template <class charT>
-void
-test(const charT* s, unsigned n)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
-    typedef typename S::traits_type T;
-    typedef typename S::allocator_type A;
-    S s2(s, n);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == n);
-    assert(T::compare(s2.data(), s, n) == 0);
-    assert(s2.get_allocator() == A());
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(const charT* s, unsigned n) {
+  typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
+  typedef typename S::traits_type T;
+  typedef typename S::allocator_type A;
+  S s2(s, n);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == n);
+  assert(T::compare(s2.data(), s, n) == 0);
+  assert(s2.get_allocator() == A());
+  assert(s2.capacity() >= s2.size());
 }
 
 template <class charT, class A>
-void
-test(const charT* s, unsigned n, const A& a)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
-    typedef typename S::traits_type T;
-    S s2(s, n, a);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == n);
-    assert(T::compare(s2.data(), s, n) == 0);
-    assert(s2.get_allocator() == a);
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(const charT* s, unsigned n, const A& a) {
+  typedef std::basic_string<charT, std::char_traits<charT>, A> S;
+  typedef typename S::traits_type T;
+  S s2(s, n, a);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == n);
+  assert(T::compare(s2.data(), s, n) == 0);
+  assert(s2.get_allocator() == a);
+  assert(s2.capacity() >= s2.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
 
     test("", 0);
@@ -91,5 +87,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
@@ -21,68 +21,60 @@
 #include "min_allocator.h"
 
 template <class charT>
-void
-test(unsigned n, charT c)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
-    typedef typename S::allocator_type A;
-    S s2(n, c);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == n);
-    for (unsigned i = 0; i < n; ++i)
-        assert(s2[i] == c);
-    assert(s2.get_allocator() == A());
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(unsigned n, charT c) {
+  typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
+  typedef typename S::allocator_type A;
+  S s2(n, c);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == n);
+  for (unsigned i = 0; i < n; ++i)
+    assert(s2[i] == c);
+  assert(s2.get_allocator() == A());
+  assert(s2.capacity() >= s2.size());
 }
 
 template <class charT, class A>
-void
-test(unsigned n, charT c, const A& a)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
-    S s2(n, c, a);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == n);
-    for (unsigned i = 0; i < n; ++i)
-        assert(s2[i] == c);
-    assert(s2.get_allocator() == a);
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(unsigned n, charT c, const A& a) {
+  typedef std::basic_string<charT, std::char_traits<charT>, A> S;
+  S s2(n, c, a);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == n);
+  for (unsigned i = 0; i < n; ++i)
+    assert(s2[i] == c);
+  assert(s2.get_allocator() == a);
+  assert(s2.capacity() >= s2.size());
 }
 
 template <class Tp>
-void
-test(Tp n, Tp c)
-{
-    typedef char charT;
-    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
-    typedef typename S::allocator_type A;
-    S s2(n, c);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == static_cast<std::size_t>(n));
-    for (int i = 0; i < n; ++i)
-        assert(s2[i] == c);
-    assert(s2.get_allocator() == A());
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(Tp n, Tp c) {
+  typedef char charT;
+  typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
+  typedef typename S::allocator_type A;
+  S s2(n, c);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == static_cast<std::size_t>(n));
+  for (int i = 0; i < n; ++i)
+    assert(s2[i] == c);
+  assert(s2.get_allocator() == A());
+  assert(s2.capacity() >= s2.size());
 }
 
 template <class Tp, class A>
-void
-test(Tp n, Tp c, const A& a)
-{
-    typedef char charT;
-    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
-    S s2(n, c, a);
-    LIBCPP_ASSERT(s2.__invariants());
-    assert(s2.size() == static_cast<std::size_t>(n));
-    for (int i = 0; i < n; ++i)
-        assert(s2[i] == c);
-    assert(s2.get_allocator() == a);
-    assert(s2.capacity() >= s2.size());
+TEST_CONSTEXPR_CXX20 void test(Tp n, Tp c, const A& a) {
+  typedef char charT;
+  typedef std::basic_string<charT, std::char_traits<charT>, A> S;
+  S s2(n, c, a);
+  LIBCPP_ASSERT(s2.__invariants());
+  assert(s2.size() == static_cast<std::size_t>(n));
+  for (int i = 0; i < n; ++i)
+    assert(s2[i] == c);
+  assert(s2.get_allocator() == a);
+  assert(s2.capacity() >= s2.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
 
     test(0, 'a');
@@ -120,6 +112,14 @@
     test(static_cast<char>(100), static_cast<char>(65), A());
     }
 #endif
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp
@@ -21,12 +21,10 @@
 #include "min_allocator.h"
 
 template <class charT>
-void
-test(std::basic_string_view<charT> sv)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
-    typedef typename S::traits_type T;
-    typedef typename S::allocator_type A;
+TEST_CONSTEXPR_CXX20 void test(std::basic_string_view<charT> sv) {
+  typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
+  typedef typename S::traits_type T;
+  typedef typename S::allocator_type A;
   {
     S s2(sv);
     LIBCPP_ASSERT(s2.__invariants());
@@ -47,11 +45,9 @@
 }
 
 template <class charT, class A>
-void
-test(std::basic_string_view<charT> sv, const A& a)
-{
-    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
-    typedef typename S::traits_type T;
+TEST_CONSTEXPR_CXX20 void test(std::basic_string_view<charT> sv, const A& a) {
+  typedef std::basic_string<charT, std::char_traits<charT>, A> S;
+  typedef typename S::traits_type T;
   {
     S s2(sv, a);
     LIBCPP_ASSERT(s2.__invariants());
@@ -71,9 +67,9 @@
   }
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
     typedef std::basic_string_view<char, std::char_traits<char> > SV;
 
@@ -108,5 +104,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp
@@ -17,20 +17,18 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
-test(S s1, SV sv)
-{
-    typedef typename S::traits_type T;
-    s1 = sv;
-    LIBCPP_ASSERT(s1.__invariants());
-    assert(s1.size() == sv.size());
-    assert(T::compare(s1.data(), sv.data(), s1.size()) == 0);
-    assert(s1.capacity() >= s1.size());
+TEST_CONSTEXPR_CXX20 void test(S s1, SV sv) {
+  typedef typename S::traits_type T;
+  s1 = sv;
+  LIBCPP_ASSERT(s1.__invariants());
+  assert(s1.size() == sv.size());
+  assert(T::compare(s1.data(), sv.data(), s1.size()) == 0);
+  assert(s1.capacity() >= s1.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     typedef std::string_view SV;
     test(S(), SV(""));
@@ -48,7 +46,7 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890"
            "1234567890123456789012345678901234567890123456789012345678901234567890"),
          SV("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"));
-    }
+  }
 #if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
@@ -71,5 +69,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp
@@ -28,121 +28,100 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S str, unsigned pos)
-{
-    typedef typename S::traits_type T;
-    typedef typename S::allocator_type A;
-
-    if (pos <= str.size())
-    {
-        S s2(str, pos);
-        LIBCPP_ASSERT(s2.__invariants());
-        typename S::size_type rlen = str.size() - pos;
-        assert(s2.size() == rlen);
-        assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
-        assert(s2.get_allocator() == A());
-        assert(s2.capacity() >= s2.size());
-    }
+TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos) {
+  typedef typename S::traits_type T;
+  typedef typename S::allocator_type A;
+
+  if (pos <= str.size()) {
+    S s2(str, pos);
+    LIBCPP_ASSERT(s2.__invariants());
+    typename S::size_type rlen = str.size() - pos;
+    assert(s2.size() == rlen);
+    assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
+    assert(s2.get_allocator() == A());
+    assert(s2.capacity() >= s2.size());
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
-        try
-        {
-            S s2(str, pos);
-            assert(false);
-        }
-        catch (std::out_of_range&)
-        {
-            assert(pos > str.size());
-        }
+  else if (!TEST_IS_CONSTANT_EVALUATED) {
+    try {
+      S s2(str, pos);
+      assert(false);
+    } catch (std::out_of_range&) {
+      assert(pos > str.size());
     }
+  }
 #endif
 }
 
 template <class S>
-void
-test(S str, unsigned pos, unsigned n)
-{
-    typedef typename S::traits_type T;
-    typedef typename S::allocator_type A;
-    if (pos <= str.size())
-    {
-        S s2(str, pos, n);
-        LIBCPP_ASSERT(s2.__invariants());
-        typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);
-        assert(s2.size() == rlen);
-        assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
-        assert(s2.get_allocator() == A());
-        assert(s2.capacity() >= s2.size());
-    }
+TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos, unsigned n) {
+  typedef typename S::traits_type T;
+  typedef typename S::allocator_type A;
+  if (pos <= str.size()) {
+    S s2(str, pos, n);
+    LIBCPP_ASSERT(s2.__invariants());
+    typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);
+    assert(s2.size() == rlen);
+    assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
+    assert(s2.get_allocator() == A());
+    assert(s2.capacity() >= s2.size());
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
-        try
-        {
-            S s2(str, pos, n);
-            assert(false);
-        }
-        catch (std::out_of_range&)
-        {
-            assert(pos > str.size());
-        }
+  else if (!TEST_IS_CONSTANT_EVALUATED) {
+    try {
+      S s2(str, pos, n);
+      assert(false);
+    } catch (std::out_of_range&) {
+      assert(pos > str.size());
     }
+  }
 #endif
 }
 
 template <class S>
-void
-test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a)
-{
-    typedef typename S::traits_type T;
-
-    if (pos <= str.size())
-    {
-        S s2(str, pos, n, a);
-        LIBCPP_ASSERT(s2.__invariants());
-        typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);
-        assert(s2.size() == rlen);
-        assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
-        assert(s2.get_allocator() == a);
-        assert(s2.capacity() >= s2.size());
-    }
+TEST_CONSTEXPR_CXX20 void test(S str, unsigned pos, unsigned n, const typename S::allocator_type& a) {
+  typedef typename S::traits_type T;
+
+  if (pos <= str.size()) {
+    S s2(str, pos, n, a);
+    LIBCPP_ASSERT(s2.__invariants());
+    typename S::size_type rlen = std::min<typename S::size_type>(str.size() - pos, n);
+    assert(s2.size() == rlen);
+    assert(T::compare(s2.data(), str.data() + pos, rlen) == 0);
+    assert(s2.get_allocator() == a);
+    assert(s2.capacity() >= s2.size());
+  }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
-    {
-        try
-        {
-            S s2(str, pos, n, a);
-            assert(false);
-        }
-        catch (std::out_of_range&)
-        {
-            assert(pos > str.size());
-        }
+  else if (!TEST_IS_CONSTANT_EVALUATED) {
+    try {
+      S s2(str, pos, n, a);
+      assert(false);
+    } catch (std::out_of_range&) {
+      assert(pos > str.size());
     }
+  }
 #endif
 }
 
 #if TEST_STD_VER >= 11
-#ifndef TEST_HAS_NO_EXCEPTIONS
-void test2583()
-{   // LWG #2583
-    typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA;
-    std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA>>> vs;
-    StringA s{"1234"};
-    vs.emplace_back(s, 2);
-
-    try { vs.emplace_back(s, 5); }
-    catch (const std::out_of_range&) { return; }
-    assert(false);
+void test2583() { // LWG #2583
+  typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA;
+  std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA> > > vs;
+  StringA s{"1234"};
+  vs.emplace_back(s, 2);
+
+  try {
+    vs.emplace_back(s, 5);
+  } catch (const std::out_of_range&) {
+    return;
+  }
+  assert(false);
 }
 #endif
-#endif
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef test_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
 
@@ -179,9 +158,9 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 1, A(8));
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8));
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8));
-    }
+  }
 #if TEST_STD_VER >= 11
-    {
+  {
     typedef min_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
 
@@ -218,11 +197,19 @@
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 1, A());
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A());
     test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A());
-    }
+  }
 
-#ifndef TEST_HAS_NO_EXCEPTIONS
+  if (!TEST_IS_CONSTANT_EVALUATED)
     test2583();
 #endif
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp b/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.contains/contains.char.pass.cpp
@@ -16,26 +16,28 @@
 
 #include "test_macros.h"
 
-void test()
-{
-    using S = std::string;
+constexpr bool test() {
+  using S = std::string;
 
-    S s1 {};
-    S s2 {"abcde", 5};
+  S s1{};
+  S s2{"abcde", 5};
 
-    ASSERT_NOEXCEPT(s1.contains('e'));
+  ASSERT_NOEXCEPT(s1.contains('e'));
 
-    assert(!s1.contains('c'));
-    assert(!s1.contains('e'));
-    assert(!s1.contains('x'));
-    assert( s2.contains('c'));
-    assert( s2.contains('e'));
-    assert(!s2.contains('x'));
+  assert(!s1.contains('c'));
+  assert(!s1.contains('e'));
+  assert(!s1.contains('x'));
+  assert(s2.contains('c'));
+  assert(s2.contains('e'));
+  assert(!s2.contains('x'));
+
+  return true;
 }
 
-int main(int, char**)
-{
-    test();
+int main(int, char**) {
+
+  test();
+  static_assert(test());
 
-    return 0;
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp b/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.contains/contains.ptr.pass.cpp
@@ -16,56 +16,58 @@
 
 #include "test_macros.h"
 
-void test()
-{
-    using S = std::string;
+constexpr bool test() {
+  using S = std::string;
 
-    const char* s = "abcde";
-    S s0;
-    S s1 {s + 4, 1};
-    S s3 {s + 2, 3};
-    S sNot {"xyz", 3};
+  const char* s = "abcde";
+  S s0;
+  S s1{s + 4, 1};
+  S s3{s + 2, 3};
+  S sNot{"xyz", 3};
 
-    assert(s0.contains(""));
-    assert(!s0.contains("e"));
+  assert(s0.contains(""));
+  assert(!s0.contains("e"));
 
-    assert( s1.contains(""));
-    assert(!s1.contains("d"));
-    assert( s1.contains("e"));
-    assert(!s1.contains("de"));
-    assert(!s1.contains("cd"));
-    assert(!s1.contains("cde"));
-    assert(!s1.contains("bcde"));
-    assert(!s1.contains("abcde"));
-    assert(!s1.contains("xyz"));
+  assert(s1.contains(""));
+  assert(!s1.contains("d"));
+  assert(s1.contains("e"));
+  assert(!s1.contains("de"));
+  assert(!s1.contains("cd"));
+  assert(!s1.contains("cde"));
+  assert(!s1.contains("bcde"));
+  assert(!s1.contains("abcde"));
+  assert(!s1.contains("xyz"));
 
-    assert( s3.contains(""));
-    assert( s3.contains("d"));
-    assert( s3.contains("e"));
-    assert( s3.contains("de"));
-    assert( s3.contains("cd"));
-    assert(!s3.contains("ce"));
-    assert( s3.contains("cde"));
-    assert(!s3.contains("edc"));
-    assert(!s3.contains("bcde"));
-    assert(!s3.contains("abcde"));
-    assert(!s3.contains("xyz"));
+  assert(s3.contains(""));
+  assert(s3.contains("d"));
+  assert(s3.contains("e"));
+  assert(s3.contains("de"));
+  assert(s3.contains("cd"));
+  assert(!s3.contains("ce"));
+  assert(s3.contains("cde"));
+  assert(!s3.contains("edc"));
+  assert(!s3.contains("bcde"));
+  assert(!s3.contains("abcde"));
+  assert(!s3.contains("xyz"));
 
-    assert( sNot.contains(""));
-    assert(!sNot.contains("d"));
-    assert(!sNot.contains("e"));
-    assert(!sNot.contains("de"));
-    assert(!sNot.contains("cd"));
-    assert(!sNot.contains("cde"));
-    assert(!sNot.contains("bcde"));
-    assert(!sNot.contains("abcde"));
-    assert( sNot.contains("xyz"));
-    assert(!sNot.contains("zyx"));
+  assert(sNot.contains(""));
+  assert(!sNot.contains("d"));
+  assert(!sNot.contains("e"));
+  assert(!sNot.contains("de"));
+  assert(!sNot.contains("cd"));
+  assert(!sNot.contains("cde"));
+  assert(!sNot.contains("bcde"));
+  assert(!sNot.contains("abcde"));
+  assert(sNot.contains("xyz"));
+  assert(!sNot.contains("zyx"));
+
+  return true;
 }
 
-int main(int, char**)
-{
-    test();
+int main(int, char**) {
+
+  test();
+  static_assert(test());
 
-    return 0;
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.contains/contains.string_view.pass.cpp
@@ -16,77 +16,79 @@
 
 #include "test_macros.h"
 
-void test()
-{
-    using S = std::string;
-    using SV = std::string_view;
-
-    const char* s = "abcde";
-    S s0;
-    S s1 {s + 1, 1};
-    S s3 {s + 1, 3};
-    S s5 {s    , 5};
-    S sNot {"xyz", 3};
-
-    SV sv0;
-    SV sv1 {s + 1, 1};
-    SV sv2 {s + 1, 2};
-    SV sv3 {s + 1, 3};
-    SV sv4 {s + 1, 4};
-    SV sv5 {s    , 5};
-    SV svNot  {"xyz", 3};
-    SV svNot2 {"bd" , 2};
-    SV svNot3 {"dcb", 3};
-
-    ASSERT_NOEXCEPT(s0.contains(sv0));
-
-    assert( s0.contains(sv0));
-    assert(!s0.contains(sv1));
-
-    assert( s1.contains(sv0));
-    assert( s1.contains(sv1));
-    assert(!s1.contains(sv2));
-    assert(!s1.contains(sv3));
-    assert(!s1.contains(sv4));
-    assert(!s1.contains(sv5));
-    assert(!s1.contains(svNot));
-    assert(!s1.contains(svNot2));
-    assert(!s1.contains(svNot3));
-
-    assert( s3.contains(sv0));
-    assert( s3.contains(sv1));
-    assert( s3.contains(sv2));
-    assert( s3.contains(sv3));
-    assert(!s3.contains(sv4));
-    assert(!s3.contains(sv5));
-    assert(!s3.contains(svNot));
-    assert(!s3.contains(svNot2));
-    assert(!s3.contains(svNot3));
-
-    assert( s5.contains(sv0));
-    assert( s5.contains(sv1));
-    assert( s5.contains(sv2));
-    assert( s5.contains(sv3));
-    assert( s5.contains(sv4));
-    assert( s5.contains(sv5));
-    assert(!s5.contains(svNot));
-    assert(!s5.contains(svNot2));
-    assert(!s5.contains(svNot3));
-
-    assert( sNot.contains(sv0));
-    assert(!sNot.contains(sv1));
-    assert(!sNot.contains(sv2));
-    assert(!sNot.contains(sv3));
-    assert(!sNot.contains(sv4));
-    assert(!sNot.contains(sv5));
-    assert( sNot.contains(svNot));
-    assert(!sNot.contains(svNot2));
-    assert(!sNot.contains(svNot3));
+constexpr bool test() {
+  using S = std::string;
+  using SV = std::string_view;
+
+  const char* s = "abcde";
+  S s0;
+  S s1{s + 1, 1};
+  S s3{s + 1, 3};
+  S s5{s, 5};
+  S sNot{"xyz", 3};
+
+  SV sv0;
+  SV sv1{s + 1, 1};
+  SV sv2{s + 1, 2};
+  SV sv3{s + 1, 3};
+  SV sv4{s + 1, 4};
+  SV sv5{s, 5};
+  SV svNot{"xyz", 3};
+  SV svNot2{"bd", 2};
+  SV svNot3{"dcb", 3};
+
+  ASSERT_NOEXCEPT(s0.contains(sv0));
+
+  assert(s0.contains(sv0));
+  assert(!s0.contains(sv1));
+
+  assert(s1.contains(sv0));
+  assert(s1.contains(sv1));
+  assert(!s1.contains(sv2));
+  assert(!s1.contains(sv3));
+  assert(!s1.contains(sv4));
+  assert(!s1.contains(sv5));
+  assert(!s1.contains(svNot));
+  assert(!s1.contains(svNot2));
+  assert(!s1.contains(svNot3));
+
+  assert(s3.contains(sv0));
+  assert(s3.contains(sv1));
+  assert(s3.contains(sv2));
+  assert(s3.contains(sv3));
+  assert(!s3.contains(sv4));
+  assert(!s3.contains(sv5));
+  assert(!s3.contains(svNot));
+  assert(!s3.contains(svNot2));
+  assert(!s3.contains(svNot3));
+
+  assert(s5.contains(sv0));
+  assert(s5.contains(sv1));
+  assert(s5.contains(sv2));
+  assert(s5.contains(sv3));
+  assert(s5.contains(sv4));
+  assert(s5.contains(sv5));
+  assert(!s5.contains(svNot));
+  assert(!s5.contains(svNot2));
+  assert(!s5.contains(svNot3));
+
+  assert(sNot.contains(sv0));
+  assert(!sNot.contains(sv1));
+  assert(!sNot.contains(sv2));
+  assert(!sNot.contains(sv3));
+  assert(!sNot.contains(sv4));
+  assert(!sNot.contains(sv5));
+  assert(sNot.contains(svNot));
+  assert(!sNot.contains(svNot2));
+  assert(!sNot.contains(svNot3));
+
+  return true;
 }
 
-int main(int, char**)
-{
-    test();
+int main(int, char**) {
+
+  test();
+  static_assert(test());
 
-    return 0;
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.char.pass.cpp
@@ -16,9 +16,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+constexpr bool test() {
+  {
     typedef std::string S;
     S  s1 {};
     S  s2 { "abcde", 5 };
@@ -29,7 +28,15 @@
     assert (!s1.ends_with('x'));
     assert ( s2.ends_with('e'));
     assert (!s2.ends_with('x'));
-    }
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+
+  test();
+  static_assert(test());
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.ptr.pass.cpp
@@ -16,9 +16,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+constexpr bool test() {
+  {
     typedef std::string S;
     const char *s = "abcde";
 
@@ -58,7 +57,15 @@
     assert (!sNot.ends_with("bcde"));
     assert (!sNot.ends_with("abcde"));
     assert ( sNot.ends_with("def"));
-    }
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+
+  test();
+  static_assert(test());
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ends_with/ends_with.string_view.pass.cpp
@@ -16,9 +16,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+constexpr bool test() {
+  {
     typedef std::string S;
     typedef std::string_view SV;
     const char *s = "abcde";
@@ -67,7 +66,15 @@
     assert (!sNot.ends_with(sv4));
     assert (!sNot.ends_with(sv5));
     assert ( sNot.ends_with(svNot));
-    }
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+
+  test();
+  static_assert(test());
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp
@@ -18,22 +18,19 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    const S& cs = s;
-    typename S::iterator b = s.begin();
-    typename S::const_iterator cb = cs.begin();
-    if (!s.empty())
-    {
-        assert(*b == s[0]);
-    }
-    assert(b == cb);
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  const S& cs = s;
+  typename S::iterator b = s.begin();
+  typename S::const_iterator cb = cs.begin();
+  if (!s.empty()) {
+    assert(*b == s[0]);
+  }
+  assert(b == cb);
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -46,5 +43,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp
@@ -17,20 +17,17 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s)
-{
-    typename S::const_iterator cb = s.cbegin();
-    if (!s.empty())
-    {
-        assert(*cb == s[0]);
-    }
-    assert(cb == s.begin());
+TEST_CONSTEXPR_CXX20 void test(const S& s) {
+  typename S::const_iterator cb = s.cbegin();
+  if (!s.empty()) {
+    assert(*cb == s[0]);
+  }
+  assert(cb == s.begin());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -43,5 +40,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp
@@ -17,16 +17,14 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s)
-{
-    typename S::const_iterator ce = s.cend();
-    assert(ce == s.end());
+TEST_CONSTEXPR_CXX20 void test(const S& s) {
+  typename S::const_iterator ce = s.cend();
+  assert(ce == s.end());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -39,5 +37,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp
@@ -17,20 +17,17 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s)
-{
-    typename S::const_reverse_iterator cb = s.crbegin();
-    if (!s.empty())
-    {
-        assert(*cb == s.back());
-    }
-    assert(cb == s.rbegin());
+TEST_CONSTEXPR_CXX20 void test(const S& s) {
+  typename S::const_reverse_iterator cb = s.crbegin();
+  if (!s.empty()) {
+    assert(*cb == s.back());
+  }
+  assert(cb == s.rbegin());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -43,5 +40,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp
@@ -17,16 +17,14 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(const S& s)
-{
-    typename S::const_reverse_iterator ce = s.crend();
-    assert(ce == s.rend());
+TEST_CONSTEXPR_CXX20 void test(const S& s) {
+  typename S::const_reverse_iterator ce = s.crend();
+  assert(ce == s.rend());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -39,5 +37,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp
@@ -19,24 +19,21 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    const S& cs = s;
-    typename S::iterator e = s.end();
-    typename S::const_iterator ce = cs.end();
-    if (s.empty())
-    {
-        assert(e == s.begin());
-        assert(ce == cs.begin());
-    }
-    assert(static_cast<std::size_t>(e - s.begin()) == s.size());
-    assert(static_cast<std::size_t>(ce - cs.begin()) == cs.size());
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  const S& cs = s;
+  typename S::iterator e = s.end();
+  typename S::const_iterator ce = cs.end();
+  if (s.empty()) {
+    assert(e == s.begin());
+    assert(ce == cs.begin());
+  }
+  assert(static_cast<std::size_t>(e - s.begin()) == s.size());
+  assert(static_cast<std::size_t>(ce - cs.begin()) == cs.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -49,5 +46,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp
@@ -22,40 +22,38 @@
 
 #include "test_macros.h"
 
-template<class C>
-void test()
-{
-    { // N3644 testing
-        typename C::iterator ii1{}, ii2{};
-        typename C::iterator ii4 = ii1;
-        typename C::const_iterator cii{};
-        assert ( ii1 == ii2 );
-        assert ( ii1 == ii4 );
+template <class C>
+TEST_CONSTEXPR_CXX20 void test() {
+  { // N3644 testing
+    typename C::iterator ii1{}, ii2{};
+    typename C::iterator ii4 = ii1;
+    typename C::const_iterator cii{};
+    assert(ii1 == ii2);
+    assert(ii1 == ii4);
 
-        assert (!(ii1 != ii2 ));
+    assert(!(ii1 != ii2));
 
-        assert ( (ii1 == cii ));
-        assert ( (cii == ii1 ));
-        assert (!(ii1 != cii ));
-        assert (!(cii != ii1 ));
-        assert (!(ii1 <  cii ));
-        assert (!(cii <  ii1 ));
-        assert ( (ii1 <= cii ));
-        assert ( (cii <= ii1 ));
-        assert (!(ii1 >  cii ));
-        assert (!(cii >  ii1 ));
-        assert ( (ii1 >= cii ));
-        assert ( (cii >= ii1 ));
-        assert (cii - ii1 == 0);
-        assert (ii1 - cii == 0);
-    }
+    assert((ii1 == cii));
+    assert((cii == ii1));
+    assert(!(ii1 != cii));
+    assert(!(cii != ii1));
+    assert(!(ii1 < cii));
+    assert(!(cii < ii1));
+    assert((ii1 <= cii));
+    assert((cii <= ii1));
+    assert(!(ii1 > cii));
+    assert(!(cii > ii1));
+    assert((ii1 >= cii));
+    assert((cii >= ii1));
+    assert(cii - ii1 == 0);
+    assert(ii1 - cii == 0);
+  }
 }
 
-int main(int, char**)
-{
-    test<std::string>();
+TEST_CONSTEXPR_CXX20 bool test() {
+  test<std::string>();
 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-    test<std::wstring>();
+  test<std::wstring>();
 #endif
 
 #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
@@ -65,5 +63,14 @@
     test<std::u16string>();
     test<std::u32string>();
 
-    return 0;
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp
@@ -18,22 +18,19 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    const S& cs = s;
-    typename S::reverse_iterator b = s.rbegin();
-    typename S::const_reverse_iterator cb = cs.rbegin();
-    if (!s.empty())
-    {
-        assert(*b == s.back());
-    }
-    assert(b == cb);
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  const S& cs = s;
+  typename S::reverse_iterator b = s.rbegin();
+  typename S::const_reverse_iterator cb = cs.rbegin();
+  if (!s.empty()) {
+    assert(*b == s.back());
+  }
+  assert(b == cb);
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -46,5 +43,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp
@@ -19,24 +19,21 @@
 #include "min_allocator.h"
 
 template <class S>
-void
-test(S s)
-{
-    const S& cs = s;
-    typename S::reverse_iterator e = s.rend();
-    typename S::const_reverse_iterator ce = cs.rend();
-    if (s.empty())
-    {
-        assert(e == s.rbegin());
-        assert(ce == cs.rbegin());
-    }
-    assert(static_cast<std::size_t>(e - s.rbegin()) == s.size());
-    assert(static_cast<std::size_t>(ce - cs.rbegin()) == cs.size());
+TEST_CONSTEXPR_CXX20 void test(S s) {
+  const S& cs = s;
+  typename S::reverse_iterator e = s.rend();
+  typename S::const_reverse_iterator ce = cs.rend();
+  if (s.empty()) {
+    assert(e == s.rbegin());
+    assert(ce == cs.rbegin());
+  }
+  assert(static_cast<std::size_t>(e - s.rbegin()) == s.size());
+  assert(static_cast<std::size_t>(ce - cs.rbegin()) == cs.size());
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20
+bool test() {
+  {
     typedef std::string S;
     test(S());
     test(S("123"));
@@ -49,5 +46,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/robust_against_adl.pass.cpp
@@ -11,25 +11,35 @@
 #include <cassert>
 #include <string>
 
+#include "test_macros.h"
+
 struct Incomplete;
 template<class T> struct Holder { T t; };
 
 template<class T>
 struct Charlike {
-    char ch_;
-    Charlike(char ch) : ch_(ch) {}
-    operator char() const { return ch_; }
+  char ch_;
+  TEST_CONSTEXPR Charlike(char ch) : ch_(ch) {}
+  TEST_CONSTEXPR operator char() const { return ch_; }
 };
 
-int main(int, char**)
-{
-    std::string s;
-    Charlike<Holder<Incomplete> > a[] = {'m', 'a', 'h', 'i'};
-    s.append(a, a+4);
-    s.assign(a, a+4);
-    s.insert(s.begin(), a, a+4);
-    s.replace(s.begin(), s.begin()+4, a, a+4);
-    assert(s == "mahimahi");
-
-    return 0;
+TEST_CONSTEXPR_CXX20 bool test() {
+  std::string s;
+  Charlike<Holder<Incomplete> > a[] = {'m', 'a', 'h', 'i'};
+  s.append(a, a+4);
+  s.assign(a, a+4);
+  s.insert(s.begin(), a, a+4);
+  s.replace(s.begin(), s.begin()+4, a, a+4);
+  assert(s == "mahimahi");
+
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp
@@ -20,7 +20,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, SV sv, typename S::size_type pos, typename S::size_type n, S expected)
 {
     if (pos <= sv.size())
@@ -30,7 +30,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -46,7 +46,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(S s, SV sv, typename S::size_type pos, S expected)
 {
     if (pos <= sv.size())
@@ -56,7 +56,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -71,7 +71,8 @@
 #endif
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -196,6 +197,14 @@
     s.append(sv, 0, std::string::npos);
     assert(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
     }
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
@@ -18,7 +18,8 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         std::string s("123");
@@ -32,5 +33,14 @@
         assert(s == "123abc");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
@@ -13,13 +13,14 @@
 
 #include <string>
 #include <cassert>
+#include <bit>
 
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "min_allocator.h"
 
 template <class S, class It>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, It first, It last, S expected)
 {
     s.append(first, last);
@@ -52,9 +53,10 @@
 }
 #endif
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
-    {
+     {
     typedef std::string S;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     test(S(), s, s, S());
@@ -173,7 +175,7 @@
     }
 #endif
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    { // test iterator operations that throw
+    if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw
     typedef std::string S;
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
@@ -216,7 +218,7 @@
     assert(s == "ABCD");
     }
 
-    { // regression-test appending to self in sneaky ways
+    if (!TEST_IS_CONSTANT_EVALUATED) { // regression-test appending to self in sneaky ways
     std::string s_short = "hello";
     std::string s_long = "Lorem ipsum dolor sit amet, consectetur/";
     std::string s_othertype = "hello";
@@ -250,5 +252,14 @@
     assert(s == "ABCD");
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, const typename S::value_type* str, S expected)
 {
     s.append(str);
@@ -26,7 +26,8 @@
     assert(s == expected);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -77,5 +78,14 @@
     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, const typename S::value_type* str, typename S::size_type n, S expected)
 {
     s.append(str, n);
@@ -27,7 +27,8 @@
     assert(s == expected);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -86,5 +87,14 @@
     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
@@ -23,7 +23,7 @@
 };
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::value_type c, S expected)
 {
     s.push_back(c);
@@ -31,8 +31,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), 'a', S(1, 'a'));
@@ -57,5 +56,14 @@
     s.push_back(vl);
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type n, typename S::value_type c, S expected)
 {
     s.append(n, c);
@@ -26,7 +26,8 @@
     assert(s == expected);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -61,5 +62,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S str, S expected)
 {
     s.append(str);
@@ -26,7 +26,8 @@
     assert(s == expected);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -86,5 +87,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
@@ -20,7 +20,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S str, typename S::size_type pos, typename S::size_type n, S expected)
 {
     if (pos <= str.size())
@@ -30,7 +30,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -46,7 +46,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(S s, S str, typename S::size_type pos, S expected)
 {
     if (pos <= str.size())
@@ -56,7 +56,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -71,7 +71,8 @@
 #endif
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -134,5 +135,14 @@
     test_npos(S(), S("12345"), 6, S("not happening"));
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, SV sv, S expected)
 {
     s.append(sv);
@@ -27,7 +27,8 @@
     assert(s == expected);
 }
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
     typedef std::string S;
@@ -80,5 +81,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, SV sv, typename S::size_type pos, typename S::size_type n, S expected)
 {
     if (pos <= sv.size())
@@ -29,7 +29,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -45,7 +45,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(S s, SV sv, typename S::size_type pos, S expected)
 {
     if (pos <= sv.size())
@@ -55,7 +55,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -70,8 +70,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -192,5 +191,14 @@
     assert(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
@@ -18,7 +18,8 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         std::string s("123");
@@ -31,6 +32,14 @@
         s.assign({'a', 'b', 'c'});
         assert(s == "abc");
     }
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S, class It>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, It first, It last, S expected)
 {
     s.assign(first, last);
@@ -52,9 +52,10 @@
 }
 #endif
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
-    {
+     {
     typedef std::string S;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     test(S(), s, s, S());
@@ -173,7 +174,7 @@
     }
 #endif
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    { // test iterator operations that throw
+    if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw
     typedef std::string S;
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
@@ -224,5 +225,14 @@
     test(sneaky, sneaky.data(), sneaky.data() + sneaky.size() + 1, expected);
     }
 
-    return 0;
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
+  return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, const typename S::value_type* str, S expected)
 {
     s.assign(str);
@@ -26,8 +26,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), "", S());
@@ -75,5 +74,14 @@
     assert(s_long == "nsectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, const typename S::value_type* str, typename S::size_type n, S expected)
 {
     s.assign(str, n);
@@ -27,8 +27,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), "", 0, S());
@@ -86,5 +85,14 @@
     assert(s_long == "rem ipsu");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S str, S expected)
 {
     s.assign(std::move(str));
@@ -27,8 +27,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), S(), S());
@@ -78,5 +77,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type n, typename S::value_type c, S expected)
 {
     s.assign(n, c);
@@ -26,8 +26,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), 0, 'a', S());
@@ -61,5 +60,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
@@ -19,7 +19,7 @@
 #include "test_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S str, S expected)
 {
     s.assign(str);
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 testAlloc(S s, S str, const typename S::allocator_type& a)
 {
     s.assign(str);
@@ -37,8 +37,7 @@
     assert(s.get_allocator() == a);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), S(), S());
@@ -114,5 +113,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
@@ -20,7 +20,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S str, typename S::size_type pos, typename S::size_type n, S expected)
 {
     if (pos <= str.size())
@@ -30,7 +30,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -46,7 +46,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(S s, S str, typename S::size_type pos, S expected)
 {
     if (pos <= str.size())
@@ -56,7 +56,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -71,8 +71,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), S(), 0, 0, S());
@@ -134,5 +133,14 @@
     test_npos(S(), S("12345"), 6, S("not happening"));
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp
@@ -20,7 +20,7 @@
 #include "test_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, SV sv, S expected)
 {
     s.assign(sv);
@@ -29,7 +29,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 testAlloc(S s, SV sv, const typename S::allocator_type& a)
 {
     s.assign(sv);
@@ -38,8 +38,7 @@
     assert(s.get_allocator() == a);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -102,5 +101,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S str, typename S::value_type* s, typename S::size_type n,
      typename S::size_type pos)
 {
@@ -33,7 +33,7 @@
             assert(S::traits_type::eq(cs[pos+r], s[r]));
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -49,8 +49,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     char s[50];
@@ -178,5 +177,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::difference_type pos, S expected)
 {
     typename S::const_iterator p = s.begin() + pos;
@@ -28,8 +28,7 @@
     assert(i - s.begin() == pos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S("abcde"), 0, S("bcde"));
@@ -63,5 +62,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::difference_type pos, typename S::difference_type n, S expected)
 {
     typename S::const_iterator first = s.cbegin() + pos;
@@ -29,8 +29,7 @@
     assert(i - s.begin() == pos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, 0, S(""));
@@ -148,5 +147,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S expected)
 {
     s.pop_back();
@@ -26,8 +26,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S("abcde"), S("abcd"));
@@ -43,5 +42,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, typename S::size_type n, S expected)
 {
     const typename S::size_type old_size = s.size();
@@ -32,7 +32,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -49,7 +49,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, S expected)
 {
     const typename S::size_type old_size = s.size();
@@ -62,7 +62,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -79,7 +79,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S expected)
 {
     s.erase();
@@ -88,8 +88,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, 0, S(""));
@@ -299,5 +298,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S& s, typename S::const_iterator p, typename S::value_type c, S expected)
 {
     bool sufficient_cap = s.size() < s.capacity();
@@ -32,8 +32,7 @@
         assert(i == p);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     S s;
@@ -73,5 +72,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
@@ -19,8 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
         std::string s("123456");
         std::string::iterator i = s.insert(s.begin() + 3, {'a', 'b', 'c'});
@@ -35,5 +34,14 @@
         assert(s == "123abc456");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S, class It>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::difference_type pos, It first, It last, S expected)
 {
     typename S::const_iterator p = s.cbegin() + pos;
@@ -33,7 +33,7 @@
 struct Widget { operator char() const { throw 42; } };
 
 template <class S, class It>
-void
+TEST_CONSTEXPR_CXX20 void
 test_exceptions(S s, typename S::difference_type pos, It first, It last)
 {
     typename S::const_iterator p = s.cbegin() + pos;
@@ -56,9 +56,8 @@
 }
 #endif
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test() {
+  {
     typedef std::string S;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     test(S(), 0, s, s, S());
@@ -151,7 +150,7 @@
     }
 #endif
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    { // test iterator operations that throw
+    if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw
     typedef std::string S;
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
@@ -194,7 +193,7 @@
     assert(s == "ABCD");
     }
 
-    { // regression-test inserting into self in sneaky ways
+    if (!TEST_IS_CONSTANT_EVALUATED) { // regression-test inserting into self in sneaky ways
     std::string s_short = "hello";
     std::string s_long = "Lorem ipsum dolor sit amet, consectetur/";
     std::string s_othertype = "hello";
@@ -232,5 +231,14 @@
     assert(s == "ABCD");
   }
 
+  return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::difference_type pos, typename S::size_type n,
      typename S::value_type c, S expected)
 {
@@ -28,8 +28,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, 0, '1', S(""));
@@ -167,5 +166,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, const typename S::value_type* str, S expected)
 {
     const typename S::size_type old_size = s.size();
@@ -31,7 +31,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -47,8 +47,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, "", S(""));
@@ -234,5 +233,14 @@
     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, const typename S::value_type* str,
      typename S::size_type n, S expected)
 {
@@ -32,7 +32,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -48,8 +48,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, "", 0, S(""));
@@ -715,5 +714,14 @@
     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, typename S::size_type n,
      typename S::value_type str, S expected)
 {
@@ -32,7 +32,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -48,8 +48,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, 0, '1', S(""));
@@ -219,5 +218,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
@@ -19,7 +19,8 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, S str, S expected)
 {
     const typename S::size_type old_size = s.size();
@@ -31,7 +32,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -47,8 +48,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, S(""), S(""));
@@ -227,5 +227,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
@@ -21,7 +21,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos1, S str, typename S::size_type pos2,
      typename S::size_type n, S expected)
 {
@@ -34,7 +34,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -51,7 +51,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(S s, typename S::size_type pos1, S str, typename S::size_type pos2, S expected)
 {
     const typename S::size_type old_size = s.size();
@@ -63,7 +63,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -81,7 +81,7 @@
 
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, S(""), 0, 0, S(""));
     test(S(""), 0, S(""), 0, 1, S(""));
@@ -136,7 +136,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), 0, S("12345678901234567890"), 0, 0, S(""));
     test(S(""), 0, S("12345678901234567890"), 0, 1, S("1"));
@@ -191,7 +191,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S(""), 1, S("1234567890"), 0, 0, S("can't happen"));
     test(S(""), 1, S("1234567890"), 0, 1, S("can't happen"));
@@ -246,7 +246,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcde"), 0, S(""), 1, 0, S("can't happen"));
     test(S("abcde"), 0, S("12345"), 0, 0, S("abcde"));
@@ -301,7 +301,7 @@
 }
 
 template <class S>
-void test4()
+TEST_CONSTEXPR_CXX20 void test4()
 {
     test(S("abcde"), 0, S("12345678901234567890"), 0, 10, S("1234567890abcde"));
     test(S("abcde"), 0, S("12345678901234567890"), 0, 19, S("1234567890123456789abcde"));
@@ -356,7 +356,7 @@
 }
 
 template <class S>
-void test5()
+TEST_CONSTEXPR_CXX20 void test5()
 {
     test(S("abcde"), 1, S("1234567890"), 0, 5, S("a12345bcde"));
     test(S("abcde"), 1, S("1234567890"), 0, 9, S("a123456789bcde"));
@@ -411,7 +411,7 @@
 }
 
 template <class S>
-void test6()
+TEST_CONSTEXPR_CXX20 void test6()
 {
     test(S("abcde"), 2, S("12345"), 0, 1, S("ab1cde"));
     test(S("abcde"), 2, S("12345"), 0, 2, S("ab12cde"));
@@ -466,7 +466,7 @@
 }
 
 template <class S>
-void test7()
+TEST_CONSTEXPR_CXX20 void test7()
 {
     test(S("abcde"), 2, S("12345678901234567890"), 0, 20, S("ab12345678901234567890cde"));
     test(S("abcde"), 2, S("12345678901234567890"), 0, 21, S("ab12345678901234567890cde"));
@@ -521,7 +521,7 @@
 }
 
 template <class S>
-void test8()
+TEST_CONSTEXPR_CXX20 void test8()
 {
     test(S("abcde"), 4, S("1234567890"), 0, 10, S("abcd1234567890e"));
     test(S("abcde"), 4, S("1234567890"), 0, 11, S("abcd1234567890e"));
@@ -576,7 +576,7 @@
 }
 
 template <class S>
-void test9()
+TEST_CONSTEXPR_CXX20 void test9()
 {
     test(S("abcde"), 5, S("12345"), 0, 4, S("abcde1234"));
     test(S("abcde"), 5, S("12345"), 0, 5, S("abcde12345"));
@@ -631,7 +631,7 @@
 }
 
 template <class S>
-void test10()
+TEST_CONSTEXPR_CXX20 void test10()
 {
     test(S("abcde"), 5, S("12345678901234567890"), 1, 0, S("abcde"));
     test(S("abcde"), 5, S("12345678901234567890"), 1, 1, S("abcde2"));
@@ -686,7 +686,7 @@
 }
 
 template <class S>
-void test11()
+TEST_CONSTEXPR_CXX20 void test11()
 {
     test(S("abcde"), 6, S("1234567890"), 1, 0, S("can't happen"));
     test(S("abcde"), 6, S("1234567890"), 1, 1, S("can't happen"));
@@ -741,7 +741,7 @@
 }
 
 template <class S>
-void test12()
+TEST_CONSTEXPR_CXX20 void test12()
 {
     test(S("abcdefghij"), 0, S("12345"), 0, 6, S("12345abcdefghij"));
     test(S("abcdefghij"), 0, S("12345"), 1, 0, S("abcdefghij"));
@@ -796,7 +796,7 @@
 }
 
 template <class S>
-void test13()
+TEST_CONSTEXPR_CXX20 void test13()
 {
     test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 9, S("234567890abcdefghij"));
     test(S("abcdefghij"), 0, S("12345678901234567890"), 1, 18, S("234567890123456789abcdefghij"));
@@ -851,7 +851,7 @@
 }
 
 template <class S>
-void test14()
+TEST_CONSTEXPR_CXX20 void test14()
 {
     test(S("abcdefghij"), 1, S("1234567890"), 1, 4, S("a2345bcdefghij"));
     test(S("abcdefghij"), 1, S("1234567890"), 1, 8, S("a23456789bcdefghij"));
@@ -906,7 +906,7 @@
 }
 
 template <class S>
-void test15()
+TEST_CONSTEXPR_CXX20 void test15()
 {
     test(S("abcdefghij"), 5, S("12345"), 1, 1, S("abcde2fghij"));
     test(S("abcdefghij"), 5, S("12345"), 1, 2, S("abcde23fghij"));
@@ -961,7 +961,7 @@
 }
 
 template <class S>
-void test16()
+TEST_CONSTEXPR_CXX20 void test16()
 {
     test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 19, S("abcde2345678901234567890fghij"));
     test(S("abcdefghij"), 5, S("12345678901234567890"), 1, 20, S("abcde2345678901234567890fghij"));
@@ -1016,7 +1016,7 @@
 }
 
 template <class S>
-void test17()
+TEST_CONSTEXPR_CXX20 void test17()
 {
     test(S("abcdefghij"), 9, S("1234567890"), 1, 9, S("abcdefghi234567890j"));
     test(S("abcdefghij"), 9, S("1234567890"), 1, 10, S("abcdefghi234567890j"));
@@ -1071,7 +1071,7 @@
 }
 
 template <class S>
-void test18()
+TEST_CONSTEXPR_CXX20 void test18()
 {
     test(S("abcdefghij"), 10, S("12345"), 1, 3, S("abcdefghij234"));
     test(S("abcdefghij"), 10, S("12345"), 1, 4, S("abcdefghij2345"));
@@ -1126,7 +1126,7 @@
 }
 
 template <class S>
-void test19()
+TEST_CONSTEXPR_CXX20 void test19()
 {
     test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 0, S("abcdefghij"));
     test(S("abcdefghij"), 10, S("12345678901234567890"), 10, 1, S("abcdefghij1"));
@@ -1181,7 +1181,7 @@
 }
 
 template <class S>
-void test20()
+TEST_CONSTEXPR_CXX20 void test20()
 {
     test(S("abcdefghij"), 11, S("1234567890"), 5, 0, S("can't happen"));
     test(S("abcdefghij"), 11, S("1234567890"), 5, 1, S("can't happen"));
@@ -1236,7 +1236,7 @@
 }
 
 template <class S>
-void test21()
+TEST_CONSTEXPR_CXX20 void test21()
 {
     test(S("abcdefghijklmnopqrst"), 0, S("12345"), 1, 5, S("2345abcdefghijklmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 0, S("12345"), 2, 0, S("abcdefghijklmnopqrst"));
@@ -1291,7 +1291,7 @@
 }
 
 template <class S>
-void test22()
+TEST_CONSTEXPR_CXX20 void test22()
 {
     test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 5, S("12345abcdefghijklmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 0, S("12345678901234567890"), 10, 9, S("123456789abcdefghijklmnopqrst"));
@@ -1346,7 +1346,7 @@
 }
 
 template <class S>
-void test23()
+TEST_CONSTEXPR_CXX20 void test23()
 {
     test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 2, S("a67bcdefghijklmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 1, S("1234567890"), 5, 4, S("a6789bcdefghijklmnopqrst"));
@@ -1401,7 +1401,7 @@
 }
 
 template <class S>
-void test24()
+TEST_CONSTEXPR_CXX20 void test24()
 {
     test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 1, S("abcdefghij3klmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 10, S("12345"), 2, 2, S("abcdefghij34klmnopqrst"));
@@ -1456,7 +1456,7 @@
 }
 
 template <class S>
-void test25()
+TEST_CONSTEXPR_CXX20 void test25()
 {
     test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 10, S("abcdefghij1234567890klmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 10, S("12345678901234567890"), 10, 11, S("abcdefghij1234567890klmnopqrst"));
@@ -1511,7 +1511,7 @@
 }
 
 template <class S>
-void test26()
+TEST_CONSTEXPR_CXX20 void test26()
 {
     test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 5, S("abcdefghijklmnopqrs67890t"));
     test(S("abcdefghijklmnopqrst"), 19, S("1234567890"), 5, 6, S("abcdefghijklmnopqrs67890t"));
@@ -1566,7 +1566,7 @@
 }
 
 template <class S>
-void test27()
+TEST_CONSTEXPR_CXX20 void test27()
 {
     test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 3, S("abcdefghijklmnopqrst345"));
     test(S("abcdefghijklmnopqrst"), 20, S("12345"), 2, 4, S("abcdefghijklmnopqrst345"));
@@ -1621,7 +1621,7 @@
 }
 
 template <class S>
-void test28()
+TEST_CONSTEXPR_CXX20 void test28()
 {
     test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 19, 0, S("abcdefghijklmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 20, S("12345678901234567890"), 19, 1, S("abcdefghijklmnopqrst0"));
@@ -1676,7 +1676,7 @@
 }
 
 template <class S>
-void test29()
+TEST_CONSTEXPR_CXX20 void test29()
 {
     test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 9, 0, S("can't happen"));
     test(S("abcdefghijklmnopqrst"), 21, S("1234567890"), 9, 1, S("can't happen"));
@@ -1711,7 +1711,7 @@
 }
 
 template <class S>
-void test30()
+TEST_CONSTEXPR_CXX20 void test30()
 {
     test_npos(S(""), 0, S("12345678901234567890"),  0, S("12345678901234567890"));
     test_npos(S(""), 0, S("12345678901234567890"),  1, S( "2345678901234567890"));
@@ -1727,9 +1727,7 @@
     test_npos(S("abcdefghijklmnopqrst"), 10, S("12345"), 6, S("can't happen"));
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test_0() {
     typedef std::string S;
     test0<S>();
     test1<S>();
@@ -1741,6 +1739,12 @@
     test7<S>();
     test8<S>();
     test9<S>();
+    
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_1() {
+    typedef std::string S;
     test10<S>();
     test11<S>();
     test12<S>();
@@ -1751,6 +1755,12 @@
     test17<S>();
     test18<S>();
     test19<S>();
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_2() {
+    typedef std::string S;
     test20<S>();
     test21<S>();
     test22<S>();
@@ -1762,9 +1772,12 @@
     test28<S>();
     test29<S>();
     test30<S>();
-    }
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_3() {
 #if TEST_STD_VER >= 11
-    {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0<S>();
     test1<S>();
@@ -1777,6 +1790,14 @@
     test8<S>();
     test9<S>();
     test10<S>();
+#endif
+    
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_4() {
+#if TEST_STD_VER >= 11
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test11<S>();
     test12<S>();
     test13<S>();
@@ -1787,6 +1808,14 @@
     test18<S>();
     test19<S>();
     test20<S>();
+#endif
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_5() {
+#if TEST_STD_VER >= 11
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test21<S>();
     test22<S>();
     test23<S>();
@@ -1797,7 +1826,25 @@
     test28<S>();
     test29<S>();
     test30<S>();
-    }
+#endif
+
+    return true;
+}
+
+int main(int, char**) {
+  test_0();
+  test_1();
+  test_2();
+  test_3();
+  test_4();
+  test_5();
+#if TEST_STD_VER > 17
+  static_assert(test_0());
+  static_assert(test_1());
+  static_assert(test_2());
+  static_assert(test_3());
+  static_assert(test_4());
+  static_assert(test_5());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos, SV sv, S expected)
 {
     const typename S::size_type old_size = s.size();
@@ -31,7 +31,7 @@
         assert(s == expected);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -47,8 +47,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -236,5 +235,14 @@
     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::value_type str, S expected)
 {
     s += str;
@@ -25,8 +25,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), 'a', S("a"));
@@ -44,5 +43,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp
@@ -18,8 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
         std::string s("123");
         s += {'a', 'b', 'c'};
@@ -32,5 +31,14 @@
         assert(s == "123abc");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, const typename S::value_type* str, S expected)
 {
     s += str;
@@ -25,8 +25,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), "", S());
@@ -76,5 +75,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, S str, S expected)
 {
     s += str;
@@ -26,8 +26,7 @@
     assert(s == expected);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(), S(), S());
@@ -86,5 +85,14 @@
     }
 #endif
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
@@ -18,8 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
         std::string s("123def456");
         s.replace(s.cbegin() + 3, s.cbegin() + 6, {'a', 'b', 'c'});
@@ -32,5 +31,14 @@
         assert(s == "123abc456");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
@@ -21,7 +21,7 @@
 #include "test_iterators.h"
 
 template <class S, class It>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l, S expected)
 {
     typename S::size_type old_size = s.size();
@@ -39,7 +39,7 @@
 struct Widget { operator char() const { throw 42; } };
 
 template <class S, class It>
-void
+TEST_CONSTEXPR_CXX20 void
 test_exceptions(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l)
 {
     typename S::const_iterator first = s.begin() + pos1;
@@ -63,10 +63,10 @@
 }
 #endif
 
-const char* str = "12345678901234567890";
+TEST_CONSTEXPR const char* str = "12345678901234567890";
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, str, str+0, S(""));
     test(S(""), 0, 0, str, str+0, S(""));
@@ -171,7 +171,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), 1, 0, str, str+4, S("a1234bcde"));
     test(S("abcde"), 1, 0, str, str+5, S("a12345bcde"));
@@ -276,7 +276,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcde"), 2, 1, str, str+5, S("ab12345de"));
     test(S("abcde"), 2, 1, str, str+9, S("ab123456789de"));
@@ -381,7 +381,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcdefghij"), 0, 0, str, str+1, S("1abcdefghij"));
     test(S("abcdefghij"), 0, 0, str, str+10, S("1234567890abcdefghij"));
@@ -486,7 +486,7 @@
 }
 
 template <class S>
-void test4()
+TEST_CONSTEXPR_CXX20 void test4()
 {
     test(S("abcdefghij"), 1, 4, str, str+0, S("afghij"));
     test(S("abcdefghij"), 1, 4, str, str+0, S("afghij"));
@@ -591,7 +591,7 @@
 }
 
 template <class S>
-void test5()
+TEST_CONSTEXPR_CXX20 void test5()
 {
     test(S("abcdefghij"), 5, 4, str, str+4, S("abcde1234j"));
     test(S("abcdefghij"), 5, 4, str, str+5, S("abcde12345j"));
@@ -696,7 +696,7 @@
 }
 
 template <class S>
-void test6()
+TEST_CONSTEXPR_CXX20 void test6()
 {
     test(S("abcdefghijklmnopqrst"), 0, 1, str, str+5, S("12345bcdefghijklmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 0, 1, str, str+9, S("123456789bcdefghijklmnopqrst"));
@@ -801,7 +801,7 @@
 }
 
 template <class S>
-void test7()
+TEST_CONSTEXPR_CXX20 void test7()
 {
     test(S("abcdefghijklmnopqrst"), 1, 9, str, str+1, S("a1klmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 1, 9, str, str+10, S("a1234567890klmnopqrst"));
@@ -906,7 +906,7 @@
 }
 
 template <class S>
-void test8()
+TEST_CONSTEXPR_CXX20 void test8()
 {
     test(S("abcdefghijklmnopqrst"), 10, 10, str, str+0, S("abcdefghij"));
     test(S("abcdefghijklmnopqrst"), 10, 10, str, str+0, S("abcdefghij"));
@@ -974,20 +974,28 @@
     test(S("abcdefghijklmnopqrst"), 20, 0, str, str+20, S("abcdefghijklmnopqrst12345678901234567890"));
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test_0() {
     typedef std::string S;
     test0<S>();
     test1<S>();
     test2<S>();
     test3<S>();
     test4<S>();
+    
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_1() {
+    typedef std::string S;
     test5<S>();
     test6<S>();
     test7<S>();
     test8<S>();
-    }
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_2() {
 #if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
@@ -996,14 +1004,27 @@
     test2<S>();
     test3<S>();
     test4<S>();
+    }
+#endif
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_3() {
+#if TEST_STD_VER >= 11
+    typedef std::string S;
     test5<S>();
     test6<S>();
     test7<S>();
     test8<S>();
-    }
 #endif
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_4() {
+    
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    { // test iterator operations that throw
+    if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw
     typedef std::string S;
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
@@ -1051,5 +1072,22 @@
     assert(s == "EFGH");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test_0();
+  test_1();
+  test_2();
+  test_3();
+  test_4();
+#if TEST_STD_VER > 17
+  static_assert(test_0());
+  static_assert(test_1());
+  static_assert(test_2());
+  static_assert(test_3());
+  static_assert(test_4());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s, typename S::size_type pos1, typename S::size_type n1, const typename S::value_type* str,
      typename S::size_type n2, S expected)
 {
@@ -35,7 +35,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, "", 0, S(""));
     test(S(""), 0, 0, "12345", 0, S(""));
@@ -140,7 +140,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), 1, 0, "12345", 4, S("a1234bcde"));
     test(S("abcde"), 1, 0, "12345", 5, S("a12345bcde"));
@@ -245,7 +245,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcde"), 2, 1, "1234567890", 5, S("ab12345de"));
     test(S("abcde"), 2, 1, "1234567890", 9, S("ab123456789de"));
@@ -350,7 +350,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcdefghij"), 0, 0, "12345678901234567890", 1, S("1abcdefghij"));
     test(S("abcdefghij"), 0, 0, "12345678901234567890", 10, S("1234567890abcdefghij"));
@@ -455,7 +455,7 @@
 }
 
 template <class S>
-void test4()
+TEST_CONSTEXPR_CXX20 void test4()
 {
     test(S("abcdefghij"), 1, 4, "", 0, S("afghij"));
     test(S("abcdefghij"), 1, 4, "12345", 0, S("afghij"));
@@ -560,7 +560,7 @@
 }
 
 template <class S>
-void test5()
+TEST_CONSTEXPR_CXX20 void test5()
 {
     test(S("abcdefghij"), 5, 4, "12345", 4, S("abcde1234j"));
     test(S("abcdefghij"), 5, 4, "12345", 5, S("abcde12345j"));
@@ -665,7 +665,7 @@
 }
 
 template <class S>
-void test6()
+TEST_CONSTEXPR_CXX20 void test6()
 {
     test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 5, S("12345bcdefghijklmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 0, 1, "1234567890", 9, S("123456789bcdefghijklmnopqrst"));
@@ -770,7 +770,7 @@
 }
 
 template <class S>
-void test7()
+TEST_CONSTEXPR_CXX20 void test7()
 {
     test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 1, S("a1klmnopqrst"));
     test(S("abcdefghijklmnopqrst"), 1, 9, "12345678901234567890", 10, S("a1234567890klmnopqrst"));
@@ -875,7 +875,7 @@
 }
 
 template <class S>
-void test8()
+TEST_CONSTEXPR_CXX20 void test8()
 {
     test(S("abcdefghijklmnopqrst"), 10, 10, "", 0, S("abcdefghij"));
     test(S("abcdefghijklmnopqrst"), 10, 10, "12345", 0, S("abcdefghij"));
@@ -943,20 +943,28 @@
     test(S("abcdefghijklmnopqrst"), 20, 0, "12345678901234567890", 20, S("abcdefghijklmnopqrst12345678901234567890"));
 }
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test_0() {
     typedef std::string S;
     test0<S>();
     test1<S>();
     test2<S>();
     test3<S>();
     test4<S>();
+    
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_1() {
+    typedef std::string S;
     test5<S>();
     test6<S>();
     test7<S>();
     test8<S>();
-    }
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_2() {
 #if TEST_STD_VER >= 11
     {
     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
@@ -965,13 +973,24 @@
     test2<S>();
     test3<S>();
     test4<S>();
+    }
+#endif
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_3() {
+#if TEST_STD_VER >= 11
+    typedef std::string S;
     test5<S>();
     test6<S>();
     test7<S>();
     test8<S>();
-    }
 #endif
 
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_4() {
     { // test replacing into self
     typedef std::string S;
     S s_short = "123/";
@@ -988,5 +1007,22 @@
     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
     }
 
+    return true;
+}
+
+int main(int, char**) {
+  test_0();
+  test_1();
+  test_2();
+  test_3();
+  test_4();
+#if TEST_STD_VER > 17
+  static_assert(test_0());
+  static_assert(test_1());
+  static_assert(test_2());
+  static_assert(test_3());
+  static_assert(test_4());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s1, S s2)
 {
     S s1_ = s1;
@@ -31,8 +31,7 @@
     assert(s2 == s1_);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""));
@@ -74,5 +73,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
@@ -21,7 +21,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(S s1, S s2)
 {
     S s1_ = s1;
@@ -33,8 +33,7 @@
     assert(s2 == s1_);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""));
@@ -75,6 +74,15 @@
     test(S("abcdefghijklmnopqrst"), S("12345678901234567890"));
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const typename S::value_type* lhs, const S& rhs, bool x)
 {
     assert((lhs != rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test("", S(""), false);
@@ -67,5 +66,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const typename S::value_type* rhs, bool x)
 {
     assert((lhs != rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", false);
@@ -67,5 +66,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp
@@ -19,14 +19,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const S& rhs, bool x)
 {
     assert((lhs != rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""), false);
@@ -68,5 +67,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, SV rhs, bool x)
 {
     assert((lhs != rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string SV;
@@ -68,5 +67,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(SV lhs, const S& rhs, bool x)
 {
     assert((lhs != rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -68,5 +67,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp
@@ -24,18 +24,18 @@
 #include "min_allocator.h"
 
 template <class S>
-void test0(typename S::value_type lhs, const S& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test0(typename S::value_type lhs, const S& rhs, const S& x) {
   assert(lhs + rhs == x);
 }
 
 #if TEST_STD_VER >= 11
 template <class S>
-void test1(typename S::value_type lhs, S&& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test1(typename S::value_type lhs, S&& rhs, const S& x) {
   assert(lhs + move(rhs) == x);
 }
 #endif
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX20 bool test() {
   {
     typedef std::string S;
     test0('a', S(""), S("a"));
@@ -52,9 +52,7 @@
     test1('a', S("12345678901234567890"), S("a12345678901234567890"));
   }
   {
-    typedef std::basic_string<char, std::char_traits<char>,
-                              min_allocator<char> >
-        S;
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0('a', S(""), S("a"));
     test0('a', S("12345"), S("a12345"));
     test0('a', S("1234567890"), S("a1234567890"));
@@ -67,5 +65,14 @@
   }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp
@@ -24,19 +24,19 @@
 #include "min_allocator.h"
 
 template <class S>
-void test0(const typename S::value_type* lhs, const S& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test0(const typename S::value_type* lhs, const S& rhs, const S& x) {
   assert(lhs + rhs == x);
 }
 
 #if TEST_STD_VER >= 11
 template <class S>
-void test1(const typename S::value_type* lhs, S&& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test1(const typename S::value_type* lhs, S&& rhs, const S& x) {
   assert(lhs + move(rhs) == x);
 }
 #endif
 
-int main(int, char**) {
-  {
+TEST_CONSTEXPR_CXX20 bool test() {
+    {
     typedef std::string S;
     test0("", S(""), S(""));
     test0("", S("12345"), S("12345"));
@@ -128,5 +128,14 @@
   }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp
@@ -24,18 +24,18 @@
 #include "min_allocator.h"
 
 template <class S>
-void test0(const S& lhs, typename S::value_type rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test0(const S& lhs, typename S::value_type rhs, const S& x) {
   assert(lhs + rhs == x);
 }
 
 #if TEST_STD_VER >= 11
 template <class S>
-void test1(S&& lhs, typename S::value_type rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test1(S&& lhs, typename S::value_type rhs, const S& x) {
   assert(move(lhs) + rhs == x);
 }
 #endif
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX20 bool test() {
   {
     typedef std::string S;
     test0(S(""), '1', S("1"));
@@ -52,9 +52,7 @@
     test1(S("abcdefghijklmnopqrst"), '1', S("abcdefghijklmnopqrst1"));
   }
   {
-    typedef std::basic_string<char, std::char_traits<char>,
-                              min_allocator<char> >
-        S;
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
     test0(S(""), '1', S("1"));
     test0(S("abcde"), '1', S("abcde1"));
     test0(S("abcdefghij"), '1', S("abcdefghij1"));
@@ -67,5 +65,14 @@
   }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp
@@ -24,18 +24,18 @@
 #include "min_allocator.h"
 
 template <class S>
-void test0(const S& lhs, const typename S::value_type* rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test0(const S& lhs, const typename S::value_type* rhs, const S& x) {
   assert(lhs + rhs == x);
 }
 
 #if TEST_STD_VER >= 11
 template <class S>
-void test1(S&& lhs, const typename S::value_type* rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test1(S&& lhs, const typename S::value_type* rhs, const S& x) {
   assert(move(lhs) + rhs == x);
 }
 #endif
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX20 bool test() {
   {
     typedef std::string S;
     test0(S(""), "", S(""));
@@ -127,5 +127,14 @@
   }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp
@@ -36,29 +36,29 @@
 #include "min_allocator.h"
 
 template <class S>
-void test0(const S& lhs, const S& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test0(const S& lhs, const S& rhs, const S& x) {
   assert(lhs + rhs == x);
 }
 
 #if TEST_STD_VER >= 11
 template <class S>
-void test1(S&& lhs, const S& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test1(S&& lhs, const S& rhs, const S& x) {
   assert(move(lhs) + rhs == x);
 }
 
 template <class S>
-void test2(const S& lhs, S&& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test2(const S& lhs, S&& rhs, const S& x) {
   assert(lhs + move(rhs) == x);
 }
 
 template <class S>
-void test3(S&& lhs, S&& rhs, const S& x) {
+TEST_CONSTEXPR_CXX20 void test3(S&& lhs, S&& rhs, const S& x) {
   assert(move(lhs) + move(rhs) == x);
 }
 
 #endif
 
-int main(int, char**) {
+TEST_CONSTEXPR_CXX20 bool test() {
   {
     typedef std::string S;
     test0(S(""), S(""), S(""));
@@ -246,5 +246,14 @@
   }
 #endif // TEST_STD_VER >= 11
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const typename S::value_type* lhs, const S& rhs, bool x)
 {
     assert((lhs == rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test("", S(""), true);
@@ -67,5 +66,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const typename S::value_type* rhs, bool x)
 {
     assert((lhs == rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", true);
@@ -67,5 +66,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, SV rhs, bool x)
 {
     assert((lhs == rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -68,5 +67,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(SV lhs, const S& rhs, bool x)
 {
     assert((lhs == rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,14 @@
     test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true);
     }
 #endif
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const typename S::value_type* lhs, const S& rhs, bool x)
 {
     assert((lhs > rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test("", S(""), false);
@@ -67,5 +66,14 @@
     }
 #endif
 
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const typename S::value_type* rhs, bool x)
 {
     assert((lhs > rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", false);
@@ -66,6 +65,15 @@
     test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp
@@ -19,14 +19,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const S& rhs, bool x)
 {
     assert((lhs > rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""), false);
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, SV rhs, bool x)
 {
     assert((lhs > rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(SV lhs, const S& rhs, bool x)
 {
     assert((lhs > rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const typename S::value_type* lhs, const S& rhs, bool x)
 {
     assert((lhs >= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test("", S(""), true);
@@ -66,6 +65,15 @@
     test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const typename S::value_type* rhs, bool x)
 {
     assert((lhs >= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", true);
@@ -66,6 +65,15 @@
     test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp
@@ -19,14 +19,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const S& rhs, bool x)
 {
     assert((lhs >= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""), true);
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, SV rhs, bool x)
 {
     assert((lhs >= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(SV lhs, const S& rhs, bool x)
 {
     assert((lhs >= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const typename S::value_type* lhs, const S& rhs, bool x)
 {
     assert((lhs < rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test("", S(""), false);
@@ -66,6 +65,15 @@
     test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const typename S::value_type* rhs, bool x)
 {
     assert((lhs < rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", false);
@@ -66,6 +65,15 @@
     test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp
@@ -19,14 +19,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const S& rhs, bool x)
 {
     assert((lhs < rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""), false);
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, SV rhs, bool x)
 {
     assert((lhs < rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(SV lhs, const S& rhs, bool x)
 {
     assert((lhs < rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const typename S::value_type* lhs, const S& rhs, bool x)
 {
     assert((lhs <= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test("", S(""), true);
@@ -66,6 +65,15 @@
     test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const typename S::value_type* rhs, bool x)
 {
     assert((lhs <= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", true);
@@ -66,6 +65,15 @@
     test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp
@@ -19,14 +19,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, const S& rhs, bool x)
 {
     assert((lhs <= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""), true);
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& lhs, SV rhs, bool x)
 {
     assert((lhs <= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp
@@ -17,14 +17,13 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(SV lhs, const S& rhs, bool x)
 {
     assert((lhs <= rhs) == x);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -67,6 +66,15 @@
     test(SV("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s)
 {
     typedef typename S::traits_type T;
@@ -31,8 +31,7 @@
         assert(T::eq(str[0], typename S::value_type()));
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""));
@@ -49,6 +48,15 @@
     test(S("abcdefghijklmnopqrst"));
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp
@@ -18,7 +18,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test_const(const S& s)
 {
     typedef typename S::traits_type T;
@@ -33,7 +33,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test_nonconst(S& s)
 {
     typedef typename S::traits_type T;
@@ -47,8 +47,7 @@
         assert(T::eq(str[0], typename S::value_type()));
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test_const(S(""));
@@ -74,6 +73,15 @@
     S s4("abcdefghijklmnopqrst"); test_nonconst(s4);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp
@@ -18,14 +18,13 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::allocator_type& a)
 {
     assert(s.get_allocator() == a);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef test_allocator<char> A;
     typedef std::basic_string<char, std::char_traits<char>, A> S;
@@ -44,6 +43,15 @@
     test(S("abcdefghijklmnopqrst", A()), A());
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp
@@ -16,7 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -26,15 +26,14 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, int x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.compare(str));
     assert(sign(s.compare(str)) == sign(x));
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), "", 0);
@@ -75,6 +74,15 @@
     test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp
@@ -22,7 +22,7 @@
 
 #include "test_macros.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -32,7 +32,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::size_type pos1, typename S::size_type n1,
      SV sv,      typename S::size_type pos2, typename S::size_type n2, int x)
 {
@@ -40,7 +40,7 @@
     if (pos1 <= s.size() && pos2 <= sv.size())
         assert(sign(s.compare(pos1, n1, sv, pos2, n2)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -56,7 +56,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(const S& s, typename S::size_type pos1, typename S::size_type n1,
           SV sv,      typename S::size_type pos2, int x)
 {
@@ -64,7 +64,7 @@
     if (pos1 <= s.size() && pos2 <= sv.size())
         assert(sign(s.compare(pos1, n1, sv, pos2)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -80,7 +80,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, SV(""), 0, 0, 0);
     test(S(""), 0, 0, SV(""), 0, 1, 0);
@@ -185,7 +185,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), 0, 1, SV("abcdefghij"), 0, 0, 0);
     test(S(""), 0, 1, SV("abcdefghij"), 0, 1, -1);
@@ -290,7 +290,7 @@
 }
 
 template <class S, class SV>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 10, 0);
     test(S(""), 1, 0, SV("abcdefghijklmnopqrst"), 0, 19, 0);
@@ -395,7 +395,7 @@
 }
 
 template <class S, class SV>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcde"), 0, 1, SV("abcde"), 0, 1, 0);
     test(S("abcde"), 0, 1, SV("abcde"), 0, 2, -1);
@@ -500,7 +500,7 @@
 }
 
 template <class S, class SV>
-void test4()
+TEST_CONSTEXPR_CXX20 void test4()
 {
     test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 10, -8);
     test(S("abcde"), 0, 2, SV("abcdefghij"), 0, 11, -8);
@@ -605,7 +605,7 @@
 }
 
 template <class S, class SV>
-void test5()
+TEST_CONSTEXPR_CXX20 void test5()
 {
     test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 0, 4);
     test(S("abcde"), 0, 4, SV("abcdefghijklmnopqrst"), 1, 1, -1);
@@ -710,7 +710,7 @@
 }
 
 template <class S, class SV>
-void test6()
+TEST_CONSTEXPR_CXX20 void test6()
 {
     test(S("abcde"), 0, 6, SV("abcde"), 0, 6, 0);
     test(S("abcde"), 0, 6, SV("abcde"), 1, 0, 5);
@@ -815,7 +815,7 @@
 }
 
 template <class S, class SV>
-void test7()
+TEST_CONSTEXPR_CXX20 void test7()
 {
     test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 4, -4);
     test(S("abcde"), 1, 0, SV("abcdefghij"), 1, 8, -8);
@@ -920,7 +920,7 @@
 }
 
 template <class S, class SV>
-void test8()
+TEST_CONSTEXPR_CXX20 void test8()
 {
     test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 19, -18);
     test(S("abcde"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 20, -18);
@@ -1025,7 +1025,7 @@
 }
 
 template <class S, class SV>
-void test9()
+TEST_CONSTEXPR_CXX20 void test9()
 {
     test(S("abcde"), 1, 3, SV("abcde"), 1, 3, 0);
     test(S("abcde"), 1, 3, SV("abcde"), 1, 4, -1);
@@ -1130,7 +1130,7 @@
 }
 
 template <class S, class SV>
-void test10()
+TEST_CONSTEXPR_CXX20 void test10()
 {
     test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 0, 4);
     test(S("abcde"), 1, 4, SV("abcdefghij"), 5, 1, -4);
@@ -1235,7 +1235,7 @@
 }
 
 template <class S, class SV>
-void test11()
+TEST_CONSTEXPR_CXX20 void test11()
 {
     test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 5, -9);
     test(S("abcde"), 1, 5, SV("abcdefghijklmnopqrst"), 10, 9, -9);
@@ -1340,7 +1340,7 @@
 }
 
 template <class S, class SV>
-void test12()
+TEST_CONSTEXPR_CXX20 void test12()
 {
     test(S("abcde"), 2, 1, SV("abcde"), 2, 1, 0);
     test(S("abcde"), 2, 1, SV("abcde"), 2, 2, -1);
@@ -1445,7 +1445,7 @@
 }
 
 template <class S, class SV>
-void test13()
+TEST_CONSTEXPR_CXX20 void test13()
 {
     test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 5, -3);
     test(S("abcde"), 2, 2, SV("abcdefghij"), 5, 6, -3);
@@ -1550,7 +1550,7 @@
 }
 
 template <class S, class SV>
-void test14()
+TEST_CONSTEXPR_CXX20 void test14()
 {
     test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 19, 0, 3);
     test(S("abcde"), 2, 3, SV("abcdefghijklmnopqrst"), 19, 1, -17);
@@ -1655,7 +1655,7 @@
 }
 
 template <class S, class SV>
-void test15()
+TEST_CONSTEXPR_CXX20 void test15()
 {
     test(S("abcde"), 4, 0, SV("abcde"), 4, 0, 0);
     test(S("abcde"), 4, 0, SV("abcde"), 4, 1, -1);
@@ -1760,7 +1760,7 @@
 }
 
 template <class S, class SV>
-void test16()
+TEST_CONSTEXPR_CXX20 void test16()
 {
     test(S("abcde"), 4, 1, SV("abcdefghij"), 9, 2, -5);
     test(S("abcde"), 4, 1, SV("abcdefghij"), 10, 0, 1);
@@ -1865,7 +1865,7 @@
 }
 
 template <class S, class SV>
-void test17()
+TEST_CONSTEXPR_CXX20 void test17()
 {
     test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 20, 1, 1);
     test(S("abcde"), 4, 2, SV("abcdefghijklmnopqrst"), 21, 0, 0);
@@ -1970,7 +1970,7 @@
 }
 
 template <class S, class SV>
-void test18()
+TEST_CONSTEXPR_CXX20 void test18()
 {
     test(S("abcde"), 5, 1, SV("abcde"), 5, 1, 0);
     test(S("abcde"), 5, 1, SV("abcde"), 6, 0, 0);
@@ -2075,7 +2075,7 @@
 }
 
 template <class S, class SV>
-void test19()
+TEST_CONSTEXPR_CXX20 void test19()
 {
     test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 0, 0);
     test(S("abcde"), 6, 0, SV("abcdefghijklmnopqrst"), 0, 1, 0);
@@ -2180,7 +2180,7 @@
 }
 
 template <class S, class SV>
-void test20()
+TEST_CONSTEXPR_CXX20 void test20()
 {
     test(S("abcdefghij"), 0, 1, SV(""), 1, 0, 0);
     test(S("abcdefghij"), 0, 1, SV("abcde"), 0, 0, 1);
@@ -2285,7 +2285,7 @@
 }
 
 template <class S, class SV>
-void test21()
+TEST_CONSTEXPR_CXX20 void test21()
 {
     test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 5, 0);
     test(S("abcdefghij"), 0, 5, SV("abcdefghij"), 0, 9, -4);
@@ -2390,7 +2390,7 @@
 }
 
 template <class S, class SV>
-void test22()
+TEST_CONSTEXPR_CXX20 void test22()
 {
     test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 20, -11);
     test(S("abcdefghij"), 0, 9, SV("abcdefghijklmnopqrst"), 0, 21, -11);
@@ -2495,7 +2495,7 @@
 }
 
 template <class S, class SV>
-void test23()
+TEST_CONSTEXPR_CXX20 void test23()
 {
     test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 4, 6);
     test(S("abcdefghij"), 0, 11, SV("abcde"), 0, 5, 5);
@@ -2600,7 +2600,7 @@
 }
 
 template <class S, class SV>
-void test24()
+TEST_CONSTEXPR_CXX20 void test24()
 {
     test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 0, 0);
     test(S("abcdefghij"), 1, 0, SV("abcdefghij"), 1, 1, -1);
@@ -2705,7 +2705,7 @@
 }
 
 template <class S, class SV>
-void test25()
+TEST_CONSTEXPR_CXX20 void test25()
 {
     test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 9, -8);
     test(S("abcdefghij"), 1, 1, SV("abcdefghijklmnopqrst"), 1, 18, -17);
@@ -2810,7 +2810,7 @@
 }
 
 template <class S, class SV>
-void test26()
+TEST_CONSTEXPR_CXX20 void test26()
 {
     test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 1, 7);
     test(S("abcdefghij"), 1, 8, SV("abcde"), 1, 2, 6);
@@ -2915,7 +2915,7 @@
 }
 
 template <class S, class SV>
-void test27()
+TEST_CONSTEXPR_CXX20 void test27()
 {
     test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 9, 0);
     test(S("abcdefghij"), 1, 9, SV("abcdefghij"), 1, 10, 0);
@@ -3020,7 +3020,7 @@
 }
 
 template <class S, class SV>
-void test28()
+TEST_CONSTEXPR_CXX20 void test28()
 {
     test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 0, 9);
     test(S("abcdefghij"), 1, 10, SV("abcdefghijklmnopqrst"), 10, 1, -9);
@@ -3125,7 +3125,7 @@
 }
 
 template <class S, class SV>
-void test29()
+TEST_CONSTEXPR_CXX20 void test29()
 {
     test(S("abcdefghij"), 5, 1, SV("abcde"), 1, 5, 4);
     test(S("abcdefghij"), 5, 1, SV("abcde"), 2, 0, 1);
@@ -3230,7 +3230,7 @@
 }
 
 template <class S, class SV>
-void test30()
+TEST_CONSTEXPR_CXX20 void test30()
 {
     test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 2, 0);
     test(S("abcdefghij"), 5, 2, SV("abcdefghij"), 5, 4, -2);
@@ -3335,7 +3335,7 @@
 }
 
 template <class S, class SV>
-void test31()
+TEST_CONSTEXPR_CXX20 void test31()
 {
     test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 10, -5);
     test(S("abcdefghij"), 5, 4, SV("abcdefghijklmnopqrst"), 10, 11, -5);
@@ -3440,7 +3440,7 @@
 }
 
 template <class S, class SV>
-void test32()
+TEST_CONSTEXPR_CXX20 void test32()
 {
     test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 3, 3);
     test(S("abcdefghij"), 5, 6, SV("abcde"), 2, 4, 3);
@@ -3545,7 +3545,7 @@
 }
 
 template <class S, class SV>
-void test33()
+TEST_CONSTEXPR_CXX20 void test33()
 {
     test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 9, 0, 0);
     test(S("abcdefghij"), 9, 0, SV("abcdefghij"), 9, 1, -1);
@@ -3650,7 +3650,7 @@
 }
 
 template <class S, class SV>
-void test34()
+TEST_CONSTEXPR_CXX20 void test34()
 {
     test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 19, 2, -10);
     test(S("abcdefghij"), 9, 1, SV("abcdefghijklmnopqrst"), 20, 0, 1);
@@ -3755,7 +3755,7 @@
 }
 
 template <class S, class SV>
-void test35()
+TEST_CONSTEXPR_CXX20 void test35()
 {
     test(S("abcdefghij"), 10, 0, SV("abcde"), 4, 2, -1);
     test(S("abcdefghij"), 10, 0, SV("abcde"), 5, 0, 0);
@@ -3860,7 +3860,7 @@
 }
 
 template <class S, class SV>
-void test36()
+TEST_CONSTEXPR_CXX20 void test36()
 {
     test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 10, 1, 0);
     test(S("abcdefghij"), 10, 1, SV("abcdefghij"), 11, 0, 0);
@@ -3965,7 +3965,7 @@
 }
 
 template <class S, class SV>
-void test37()
+TEST_CONSTEXPR_CXX20 void test37()
 {
     test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0, 0, 0);
     test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0, 1, 0);
@@ -4070,7 +4070,7 @@
 }
 
 template <class S, class SV>
-void test38()
+TEST_CONSTEXPR_CXX20 void test38()
 {
     test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 0, 1);
     test(S("abcdefghijklmnopqrst"), 0, 1, SV("abcdefghij"), 0, 1, 0);
@@ -4175,7 +4175,7 @@
 }
 
 template <class S, class SV>
-void test39()
+TEST_CONSTEXPR_CXX20 void test39()
 {
     test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 10, 0);
     test(S("abcdefghijklmnopqrst"), 0, 10, SV("abcdefghijklmnopqrst"), 0, 19, -9);
@@ -4280,7 +4280,7 @@
 }
 
 template <class S, class SV>
-void test40()
+TEST_CONSTEXPR_CXX20 void test40()
 {
     test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 1, 19);
     test(S("abcdefghijklmnopqrst"), 0, 20, SV("abcde"), 0, 2, 18);
@@ -4385,7 +4385,7 @@
 }
 
 template <class S, class SV>
-void test41()
+TEST_CONSTEXPR_CXX20 void test41()
 {
     test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 10, 10);
     test(S("abcdefghijklmnopqrst"), 0, 21, SV("abcdefghij"), 0, 11, 10);
@@ -4490,7 +4490,7 @@
 }
 
 template <class S, class SV>
-void test42()
+TEST_CONSTEXPR_CXX20 void test42()
 {
     test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 0, 0);
     test(S("abcdefghijklmnopqrst"), 1, 0, SV("abcdefghijklmnopqrst"), 1, 1, -1);
@@ -4595,7 +4595,7 @@
 }
 
 template <class S, class SV>
-void test43()
+TEST_CONSTEXPR_CXX20 void test43()
 {
     test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 0, 6, 1);
     test(S("abcdefghijklmnopqrst"), 1, 9, SV("abcde"), 1, 0, 9);
@@ -4700,7 +4700,7 @@
 }
 
 template <class S, class SV>
-void test44()
+TEST_CONSTEXPR_CXX20 void test44()
 {
     test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 4, 14);
     test(S("abcdefghijklmnopqrst"), 1, 18, SV("abcdefghij"), 1, 8, 10);
@@ -4805,7 +4805,7 @@
 }
 
 template <class S, class SV>
-void test45()
+TEST_CONSTEXPR_CXX20 void test45()
 {
     test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 19, 0);
     test(S("abcdefghijklmnopqrst"), 1, 19, SV("abcdefghijklmnopqrst"), 1, 20, 0);
@@ -4910,7 +4910,7 @@
 }
 
 template <class S, class SV>
-void test46()
+TEST_CONSTEXPR_CXX20 void test46()
 {
     test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 3, -3);
     test(S("abcdefghijklmnopqrst"), 10, 0, SV("abcde"), 1, 4, -4);
@@ -5015,7 +5015,7 @@
 }
 
 template <class S, class SV>
-void test47()
+TEST_CONSTEXPR_CXX20 void test47()
 {
     test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 0, 1);
     test(S("abcdefghijklmnopqrst"), 10, 1, SV("abcdefghij"), 5, 1, 5);
@@ -5120,7 +5120,7 @@
 }
 
 template <class S, class SV>
-void test48()
+TEST_CONSTEXPR_CXX20 void test48()
 {
     test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 5, 0);
     test(S("abcdefghijklmnopqrst"), 10, 5, SV("abcdefghijklmnopqrst"), 10, 9, -4);
@@ -5225,7 +5225,7 @@
 }
 
 template <class S, class SV>
-void test49()
+TEST_CONSTEXPR_CXX20 void test49()
 {
     test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 1, 8);
     test(S("abcdefghijklmnopqrst"), 10, 10, SV("abcde"), 2, 2, 8);
@@ -5330,7 +5330,7 @@
 }
 
 template <class S, class SV>
-void test50()
+TEST_CONSTEXPR_CXX20 void test50()
 {
     test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 5, 5);
     test(S("abcdefghijklmnopqrst"), 10, 11, SV("abcdefghij"), 5, 6, 5);
@@ -5435,7 +5435,7 @@
 }
 
 template <class S, class SV>
-void test51()
+TEST_CONSTEXPR_CXX20 void test51()
 {
     test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 19, 0, 0);
     test(S("abcdefghijklmnopqrst"), 19, 0, SV("abcdefghijklmnopqrst"), 19, 1, -1);
@@ -5540,7 +5540,7 @@
 }
 
 template <class S, class SV>
-void test52()
+TEST_CONSTEXPR_CXX20 void test52()
 {
     test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 4, 0, 1);
     test(S("abcdefghijklmnopqrst"), 19, 2, SV("abcde"), 4, 1, 15);
@@ -5645,7 +5645,7 @@
 }
 
 template <class S, class SV>
-void test53()
+TEST_CONSTEXPR_CXX20 void test53()
 {
     test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 9, 2, -1);
     test(S("abcdefghijklmnopqrst"), 20, 0, SV("abcdefghij"), 10, 0, 0);
@@ -5750,7 +5750,7 @@
 }
 
 template <class S, class SV>
-void test54()
+TEST_CONSTEXPR_CXX20 void test54()
 {
     test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 20, 1, 0);
     test(S("abcdefghijklmnopqrst"), 20, 1, SV("abcdefghijklmnopqrst"), 21, 0, 0);
@@ -5831,7 +5831,7 @@
 }
 
 template <class S, class SV>
-void test55()
+TEST_CONSTEXPR_CXX20 void test55()
 {
     test_npos(S(""), 0, 0, SV(""), 0, 0);
     test_npos(S(""), 0, 0, SV("abcde"), 0, -5);
@@ -5840,72 +5840,8 @@
     test_npos(S("abcde"), 0, 0, SV("abcdefghij"), 5, -5);
 }
 
-int main(int, char**)
-{
-    {
-    typedef std::string S;
-    typedef std::string_view SV;
-    test0<S, SV>();
-    test1<S, SV>();
-    test2<S, SV>();
-    test3<S, SV>();
-    test4<S, SV>();
-    test5<S, SV>();
-    test6<S, SV>();
-    test7<S, SV>();
-    test8<S, SV>();
-    test9<S, SV>();
-    test10<S, SV>();
-    test11<S, SV>();
-    test12<S, SV>();
-    test13<S, SV>();
-    test14<S, SV>();
-    test15<S, SV>();
-    test16<S, SV>();
-    test17<S, SV>();
-    test18<S, SV>();
-    test19<S, SV>();
-    test20<S, SV>();
-    test21<S, SV>();
-    test22<S, SV>();
-    test23<S, SV>();
-    test24<S, SV>();
-    test25<S, SV>();
-    test26<S, SV>();
-    test27<S, SV>();
-    test28<S, SV>();
-    test29<S, SV>();
-    test30<S, SV>();
-    test31<S, SV>();
-    test32<S, SV>();
-    test33<S, SV>();
-    test34<S, SV>();
-    test35<S, SV>();
-    test36<S, SV>();
-    test37<S, SV>();
-    test38<S, SV>();
-    test39<S, SV>();
-    test40<S, SV>();
-    test41<S, SV>();
-    test42<S, SV>();
-    test43<S, SV>();
-    test44<S, SV>();
-    test45<S, SV>();
-    test46<S, SV>();
-    test47<S, SV>();
-    test48<S, SV>();
-    test49<S, SV>();
-    test50<S, SV>();
-    test51<S, SV>();
-    test52<S, SV>();
-    test53<S, SV>();
-    test54<S, SV>();
-    test55<S, SV>();
-    }
-#if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
-    typedef std::basic_string_view<char, std::char_traits<char>> SV;
+template<class S, class SV>
+TEST_CONSTEXPR_CXX20 bool test_0() {
     test0<S, SV>();
     test1<S, SV>();
     test2<S, SV>();
@@ -5919,6 +5855,12 @@
     test10<S, SV>();
     test11<S, SV>();
     test12<S, SV>();
+
+    return true;
+}
+
+template<class S, class SV>
+TEST_CONSTEXPR_CXX20 bool test_1() {
     test13<S, SV>();
     test14<S, SV>();
     test15<S, SV>();
@@ -5933,6 +5875,12 @@
     test24<S, SV>();
     test25<S, SV>();
     test26<S, SV>();
+
+    return true;
+}
+
+template<class S, class SV>
+TEST_CONSTEXPR_CXX20 bool test_2() {
     test27<S, SV>();
     test28<S, SV>();
     test29<S, SV>();
@@ -5947,6 +5895,12 @@
     test38<S, SV>();
     test39<S, SV>();
     test40<S, SV>();
+
+    return true;
+}
+
+template<class S, class SV>
+TEST_CONSTEXPR_CXX20 bool test_3() {
     test41<S, SV>();
     test42<S, SV>();
     test43<S, SV>();
@@ -5962,8 +5916,11 @@
     test53<S, SV>();
     test54<S, SV>();
     test55<S, SV>();
-    }
-#endif
+
+    return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_4() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -5989,6 +5946,52 @@
 //  calls compare(size, size, string(arr), 0, npos)
     assert(s.compare(0, 4, arr, 0, std::string::npos) == 0);
     }
+    
+  return true;
+}
+
+int main() {
+  {
+    typedef std::string S;
+    typedef std::string_view SV;
+    test_0<S, SV>();
+    test_1<S, SV>();
+    test_2<S, SV>();
+    test_3<S, SV>();
+    test_4();
+  }
+#if TEST_STD_VER >= 11
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    typedef std::basic_string_view<char, std::char_traits<char>> SV;
+    test_0<S, SV>();
+    test_1<S, SV>();
+    test_2<S, SV>();
+    test_3<S, SV>();
+    test_4();
+  }
+#endif
+
+#if TEST_STD_VER > 17
+  {
+    typedef std::string S;
+    typedef std::string_view SV;
+    static_assert(test_0<S, SV>());
+    static_assert(test_1<S, SV>());
+    static_assert(test_2<S, SV>());
+    static_assert(test_3<S, SV>());
+    static_assert(test_4());
+  }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    typedef std::basic_string_view<char, std::char_traits<char>> SV;
+    static_assert(test_0<S, SV>());
+    static_assert(test_1<S, SV>());
+    static_assert(test_2<S, SV>());
+    static_assert(test_3<S, SV>());
+    static_assert(test_4());
+  }
+#endif
 
   return 0;
-}
+}
\ No newline at end of file
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
@@ -18,7 +18,7 @@
 
 #include "test_macros.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -28,14 +28,14 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::size_type pos1, typename S::size_type n1,
      const typename S::value_type* str, int x)
 {
     if (pos1 <= s.size())
         assert(sign(s.compare(pos1, n1, str)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -51,7 +51,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, "", 0);
     test(S(""), 0, 0, "abcde", -5);
@@ -156,7 +156,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), 6, 0, "", 0);
     test(S("abcde"), 6, 0, "abcde", 0);
@@ -261,7 +261,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcdefghijklmnopqrst"), 0, 0, "", 0);
     test(S("abcdefghijklmnopqrst"), 0, 0, "abcde", -5);
@@ -361,8 +361,7 @@
     test(S("abcdefghijklmnopqrst"), 21, 0, "abcdefghijklmnopqrst", 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -377,6 +376,15 @@
     test2<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp
@@ -18,7 +18,7 @@
 
 #include "test_macros.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -28,14 +28,14 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::size_type pos, typename S::size_type n1,
      const typename S::value_type* str, typename S::size_type n2, int x)
 {
     if (pos <= s.size())
         assert(sign(s.compare(pos, n1, str, n2)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -51,7 +51,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, "", 0, 0);
     test(S(""), 0, 0, "abcde", 0, 0);
@@ -156,7 +156,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), 0, 4, "abcde", 4, 0);
     test(S("abcde"), 0, 4, "abcde", 5, -1);
@@ -261,7 +261,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcde"), 1, 3, "abcdefghij", 5, 1);
     test(S("abcde"), 1, 3, "abcdefghij", 9, 1);
@@ -366,7 +366,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcde"), 2, 3, "abcdefghijklmnopqrst", 1, 2);
     test(S("abcde"), 2, 3, "abcdefghijklmnopqrst", 10, 2);
@@ -471,7 +471,7 @@
 }
 
 template <class S>
-void test4()
+TEST_CONSTEXPR_CXX20 void test4()
 {
     test(S("abcde"), 6, 0, "", 0, 0);
     test(S("abcde"), 6, 0, "abcde", 0, 0);
@@ -576,7 +576,7 @@
 }
 
 template <class S>
-void test5()
+TEST_CONSTEXPR_CXX20 void test5()
 {
     test(S("abcdefghij"), 0, 11, "abcde", 4, 6);
     test(S("abcdefghij"), 0, 11, "abcde", 5, 5);
@@ -681,7 +681,7 @@
 }
 
 template <class S>
-void test6()
+TEST_CONSTEXPR_CXX20 void test6()
 {
     test(S("abcdefghij"), 1, 10, "abcdefghij", 5, 1);
     test(S("abcdefghij"), 1, 10, "abcdefghij", 9, 1);
@@ -786,7 +786,7 @@
 }
 
 template <class S>
-void test7()
+TEST_CONSTEXPR_CXX20 void test7()
 {
     test(S("abcdefghij"), 5, 6, "abcdefghijklmnopqrst", 1, 5);
     test(S("abcdefghij"), 5, 6, "abcdefghijklmnopqrst", 10, 5);
@@ -891,7 +891,7 @@
 }
 
 template <class S>
-void test8()
+TEST_CONSTEXPR_CXX20 void test8()
 {
     test(S("abcdefghijklmnopqrst"), 0, 0, "", 0, 0);
     test(S("abcdefghijklmnopqrst"), 0, 0, "abcde", 0, 0);
@@ -996,7 +996,7 @@
 }
 
 template <class S>
-void test9()
+TEST_CONSTEXPR_CXX20 void test9()
 {
     test(S("abcdefghijklmnopqrst"), 1, 0, "abcde", 4, -4);
     test(S("abcdefghijklmnopqrst"), 1, 0, "abcde", 5, -5);
@@ -1101,7 +1101,7 @@
 }
 
 template <class S>
-void test10()
+TEST_CONSTEXPR_CXX20 void test10()
 {
     test(S("abcdefghijklmnopqrst"), 10, 0, "abcdefghij", 5, -5);
     test(S("abcdefghijklmnopqrst"), 10, 0, "abcdefghij", 9, -9);
@@ -1206,7 +1206,7 @@
 }
 
 template <class S>
-void test11()
+TEST_CONSTEXPR_CXX20 void test11()
 {
     test(S("abcdefghijklmnopqrst"), 19, 0, "abcdefghijklmnopqrst", 1, -1);
     test(S("abcdefghijklmnopqrst"), 19, 0, "abcdefghijklmnopqrst", 10, -10);
@@ -1294,8 +1294,7 @@
     test(S("abcdefghijklmnopqrst"), 21, 0, "abcdefghijklmnopqrst", 20, 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -1328,6 +1327,15 @@
     test11<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -27,14 +27,14 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::size_type pos1, typename S::size_type n1,
      const S& str, int x)
 {
     if (pos1 <= s.size())
         assert(sign(s.compare(pos1, n1, str)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -50,7 +50,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, S(""), 0);
     test(S(""), 0, 0, S("abcde"), -5);
@@ -155,7 +155,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), 6, 0, S(""), 0);
     test(S("abcde"), 6, 0, S("abcde"), 0);
@@ -260,7 +260,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcdefghijklmnopqrst"), 0, 0, S(""), 0);
     test(S("abcdefghijklmnopqrst"), 0, 0, S("abcde"), -5);
@@ -360,8 +360,7 @@
     test(S("abcdefghijklmnopqrst"), 21, 0, S("abcdefghijklmnopqrst"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -383,6 +382,15 @@
     assert(s.compare(0, 1, {"abc", 1}) < 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp
@@ -20,7 +20,7 @@
 
 #include "test_macros.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -30,14 +30,14 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s,   typename S::size_type pos1, typename S::size_type n1,
      const S& str, typename S::size_type pos2, typename S::size_type n2, int x)
 {
     if (pos1 <= s.size() && pos2 <= str.size())
         assert(sign(s.compare(pos1, n1, str, pos2, n2)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -53,7 +53,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test_npos(const S& s,   typename S::size_type pos1, typename S::size_type n1,
           const S& str, typename S::size_type pos2, int x)
 {
@@ -76,7 +76,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, S(""), 0, 0, 0);
     test(S(""), 0, 0, S(""), 0, 1, 0);
@@ -181,7 +181,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), 0, 1, S("abcdefghij"), 0, 0, 0);
     test(S(""), 0, 1, S("abcdefghij"), 0, 1, -1);
@@ -286,7 +286,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S(""), 1, 0, S("abcdefghijklmnopqrst"), 0, 10, 0);
     test(S(""), 1, 0, S("abcdefghijklmnopqrst"), 0, 19, 0);
@@ -391,7 +391,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcde"), 0, 1, S("abcde"), 0, 1, 0);
     test(S("abcde"), 0, 1, S("abcde"), 0, 2, -1);
@@ -496,7 +496,7 @@
 }
 
 template <class S>
-void test4()
+TEST_CONSTEXPR_CXX20 void test4()
 {
     test(S("abcde"), 0, 2, S("abcdefghij"), 0, 10, -8);
     test(S("abcde"), 0, 2, S("abcdefghij"), 0, 11, -8);
@@ -601,7 +601,7 @@
 }
 
 template <class S>
-void test5()
+TEST_CONSTEXPR_CXX20 void test5()
 {
     test(S("abcde"), 0, 4, S("abcdefghijklmnopqrst"), 1, 0, 4);
     test(S("abcde"), 0, 4, S("abcdefghijklmnopqrst"), 1, 1, -1);
@@ -706,7 +706,7 @@
 }
 
 template <class S>
-void test6()
+TEST_CONSTEXPR_CXX20 void test6()
 {
     test(S("abcde"), 0, 6, S("abcde"), 0, 6, 0);
     test(S("abcde"), 0, 6, S("abcde"), 1, 0, 5);
@@ -811,7 +811,7 @@
 }
 
 template <class S>
-void test7()
+TEST_CONSTEXPR_CXX20 void test7()
 {
     test(S("abcde"), 1, 0, S("abcdefghij"), 1, 4, -4);
     test(S("abcde"), 1, 0, S("abcdefghij"), 1, 8, -8);
@@ -916,7 +916,7 @@
 }
 
 template <class S>
-void test8()
+TEST_CONSTEXPR_CXX20 void test8()
 {
     test(S("abcde"), 1, 1, S("abcdefghijklmnopqrst"), 1, 19, -18);
     test(S("abcde"), 1, 1, S("abcdefghijklmnopqrst"), 1, 20, -18);
@@ -1021,7 +1021,7 @@
 }
 
 template <class S>
-void test9()
+TEST_CONSTEXPR_CXX20 void test9()
 {
     test(S("abcde"), 1, 3, S("abcde"), 1, 3, 0);
     test(S("abcde"), 1, 3, S("abcde"), 1, 4, -1);
@@ -1126,7 +1126,7 @@
 }
 
 template <class S>
-void test10()
+TEST_CONSTEXPR_CXX20 void test10()
 {
     test(S("abcde"), 1, 4, S("abcdefghij"), 5, 0, 4);
     test(S("abcde"), 1, 4, S("abcdefghij"), 5, 1, -4);
@@ -1231,7 +1231,7 @@
 }
 
 template <class S>
-void test11()
+TEST_CONSTEXPR_CXX20 void test11()
 {
     test(S("abcde"), 1, 5, S("abcdefghijklmnopqrst"), 10, 5, -9);
     test(S("abcde"), 1, 5, S("abcdefghijklmnopqrst"), 10, 9, -9);
@@ -1336,7 +1336,7 @@
 }
 
 template <class S>
-void test12()
+TEST_CONSTEXPR_CXX20 void test12()
 {
     test(S("abcde"), 2, 1, S("abcde"), 2, 1, 0);
     test(S("abcde"), 2, 1, S("abcde"), 2, 2, -1);
@@ -1441,7 +1441,7 @@
 }
 
 template <class S>
-void test13()
+TEST_CONSTEXPR_CXX20 void test13()
 {
     test(S("abcde"), 2, 2, S("abcdefghij"), 5, 5, -3);
     test(S("abcde"), 2, 2, S("abcdefghij"), 5, 6, -3);
@@ -1546,7 +1546,7 @@
 }
 
 template <class S>
-void test14()
+TEST_CONSTEXPR_CXX20 void test14()
 {
     test(S("abcde"), 2, 3, S("abcdefghijklmnopqrst"), 19, 0, 3);
     test(S("abcde"), 2, 3, S("abcdefghijklmnopqrst"), 19, 1, -17);
@@ -1651,7 +1651,7 @@
 }
 
 template <class S>
-void test15()
+TEST_CONSTEXPR_CXX20 void test15()
 {
     test(S("abcde"), 4, 0, S("abcde"), 4, 0, 0);
     test(S("abcde"), 4, 0, S("abcde"), 4, 1, -1);
@@ -1756,7 +1756,7 @@
 }
 
 template <class S>
-void test16()
+TEST_CONSTEXPR_CXX20 void test16()
 {
     test(S("abcde"), 4, 1, S("abcdefghij"), 9, 2, -5);
     test(S("abcde"), 4, 1, S("abcdefghij"), 10, 0, 1);
@@ -1861,7 +1861,7 @@
 }
 
 template <class S>
-void test17()
+TEST_CONSTEXPR_CXX20 void test17()
 {
     test(S("abcde"), 4, 2, S("abcdefghijklmnopqrst"), 20, 1, 1);
     test(S("abcde"), 4, 2, S("abcdefghijklmnopqrst"), 21, 0, 0);
@@ -1966,7 +1966,7 @@
 }
 
 template <class S>
-void test18()
+TEST_CONSTEXPR_CXX20 void test18()
 {
     test(S("abcde"), 5, 1, S("abcde"), 5, 1, 0);
     test(S("abcde"), 5, 1, S("abcde"), 6, 0, 0);
@@ -2071,7 +2071,7 @@
 }
 
 template <class S>
-void test19()
+TEST_CONSTEXPR_CXX20 void test19()
 {
     test(S("abcde"), 6, 0, S("abcdefghijklmnopqrst"), 0, 0, 0);
     test(S("abcde"), 6, 0, S("abcdefghijklmnopqrst"), 0, 1, 0);
@@ -2176,7 +2176,7 @@
 }
 
 template <class S>
-void test20()
+TEST_CONSTEXPR_CXX20 void test20()
 {
     test(S("abcdefghij"), 0, 1, S(""), 1, 0, 0);
     test(S("abcdefghij"), 0, 1, S("abcde"), 0, 0, 1);
@@ -2281,7 +2281,7 @@
 }
 
 template <class S>
-void test21()
+TEST_CONSTEXPR_CXX20 void test21()
 {
     test(S("abcdefghij"), 0, 5, S("abcdefghij"), 0, 5, 0);
     test(S("abcdefghij"), 0, 5, S("abcdefghij"), 0, 9, -4);
@@ -2386,7 +2386,7 @@
 }
 
 template <class S>
-void test22()
+TEST_CONSTEXPR_CXX20 void test22()
 {
     test(S("abcdefghij"), 0, 9, S("abcdefghijklmnopqrst"), 0, 20, -11);
     test(S("abcdefghij"), 0, 9, S("abcdefghijklmnopqrst"), 0, 21, -11);
@@ -2491,7 +2491,7 @@
 }
 
 template <class S>
-void test23()
+TEST_CONSTEXPR_CXX20 void test23()
 {
     test(S("abcdefghij"), 0, 11, S("abcde"), 0, 4, 6);
     test(S("abcdefghij"), 0, 11, S("abcde"), 0, 5, 5);
@@ -2596,7 +2596,7 @@
 }
 
 template <class S>
-void test24()
+TEST_CONSTEXPR_CXX20 void test24()
 {
     test(S("abcdefghij"), 1, 0, S("abcdefghij"), 1, 0, 0);
     test(S("abcdefghij"), 1, 0, S("abcdefghij"), 1, 1, -1);
@@ -2701,7 +2701,7 @@
 }
 
 template <class S>
-void test25()
+TEST_CONSTEXPR_CXX20 void test25()
 {
     test(S("abcdefghij"), 1, 1, S("abcdefghijklmnopqrst"), 1, 9, -8);
     test(S("abcdefghij"), 1, 1, S("abcdefghijklmnopqrst"), 1, 18, -17);
@@ -2806,7 +2806,7 @@
 }
 
 template <class S>
-void test26()
+TEST_CONSTEXPR_CXX20 void test26()
 {
     test(S("abcdefghij"), 1, 8, S("abcde"), 1, 1, 7);
     test(S("abcdefghij"), 1, 8, S("abcde"), 1, 2, 6);
@@ -2911,7 +2911,7 @@
 }
 
 template <class S>
-void test27()
+TEST_CONSTEXPR_CXX20 void test27()
 {
     test(S("abcdefghij"), 1, 9, S("abcdefghij"), 1, 9, 0);
     test(S("abcdefghij"), 1, 9, S("abcdefghij"), 1, 10, 0);
@@ -3016,7 +3016,7 @@
 }
 
 template <class S>
-void test28()
+TEST_CONSTEXPR_CXX20 void test28()
 {
     test(S("abcdefghij"), 1, 10, S("abcdefghijklmnopqrst"), 10, 0, 9);
     test(S("abcdefghij"), 1, 10, S("abcdefghijklmnopqrst"), 10, 1, -9);
@@ -3121,7 +3121,7 @@
 }
 
 template <class S>
-void test29()
+TEST_CONSTEXPR_CXX20 void test29()
 {
     test(S("abcdefghij"), 5, 1, S("abcde"), 1, 5, 4);
     test(S("abcdefghij"), 5, 1, S("abcde"), 2, 0, 1);
@@ -3226,7 +3226,7 @@
 }
 
 template <class S>
-void test30()
+TEST_CONSTEXPR_CXX20 void test30()
 {
     test(S("abcdefghij"), 5, 2, S("abcdefghij"), 5, 2, 0);
     test(S("abcdefghij"), 5, 2, S("abcdefghij"), 5, 4, -2);
@@ -3331,7 +3331,7 @@
 }
 
 template <class S>
-void test31()
+TEST_CONSTEXPR_CXX20 void test31()
 {
     test(S("abcdefghij"), 5, 4, S("abcdefghijklmnopqrst"), 10, 10, -5);
     test(S("abcdefghij"), 5, 4, S("abcdefghijklmnopqrst"), 10, 11, -5);
@@ -3436,7 +3436,7 @@
 }
 
 template <class S>
-void test32()
+TEST_CONSTEXPR_CXX20 void test32()
 {
     test(S("abcdefghij"), 5, 6, S("abcde"), 2, 3, 3);
     test(S("abcdefghij"), 5, 6, S("abcde"), 2, 4, 3);
@@ -3541,7 +3541,7 @@
 }
 
 template <class S>
-void test33()
+TEST_CONSTEXPR_CXX20 void test33()
 {
     test(S("abcdefghij"), 9, 0, S("abcdefghij"), 9, 0, 0);
     test(S("abcdefghij"), 9, 0, S("abcdefghij"), 9, 1, -1);
@@ -3646,7 +3646,7 @@
 }
 
 template <class S>
-void test34()
+TEST_CONSTEXPR_CXX20 void test34()
 {
     test(S("abcdefghij"), 9, 1, S("abcdefghijklmnopqrst"), 19, 2, -10);
     test(S("abcdefghij"), 9, 1, S("abcdefghijklmnopqrst"), 20, 0, 1);
@@ -3751,7 +3751,7 @@
 }
 
 template <class S>
-void test35()
+TEST_CONSTEXPR_CXX20 void test35()
 {
     test(S("abcdefghij"), 10, 0, S("abcde"), 4, 2, -1);
     test(S("abcdefghij"), 10, 0, S("abcde"), 5, 0, 0);
@@ -3856,7 +3856,7 @@
 }
 
 template <class S>
-void test36()
+TEST_CONSTEXPR_CXX20 void test36()
 {
     test(S("abcdefghij"), 10, 1, S("abcdefghij"), 10, 1, 0);
     test(S("abcdefghij"), 10, 1, S("abcdefghij"), 11, 0, 0);
@@ -3961,7 +3961,7 @@
 }
 
 template <class S>
-void test37()
+TEST_CONSTEXPR_CXX20 void test37()
 {
     test(S("abcdefghijklmnopqrst"), 0, 0, S(""), 0, 0, 0);
     test(S("abcdefghijklmnopqrst"), 0, 0, S(""), 0, 1, 0);
@@ -4066,7 +4066,7 @@
 }
 
 template <class S>
-void test38()
+TEST_CONSTEXPR_CXX20 void test38()
 {
     test(S("abcdefghijklmnopqrst"), 0, 1, S("abcdefghij"), 0, 0, 1);
     test(S("abcdefghijklmnopqrst"), 0, 1, S("abcdefghij"), 0, 1, 0);
@@ -4171,7 +4171,7 @@
 }
 
 template <class S>
-void test39()
+TEST_CONSTEXPR_CXX20 void test39()
 {
     test(S("abcdefghijklmnopqrst"), 0, 10, S("abcdefghijklmnopqrst"), 0, 10, 0);
     test(S("abcdefghijklmnopqrst"), 0, 10, S("abcdefghijklmnopqrst"), 0, 19, -9);
@@ -4276,7 +4276,7 @@
 }
 
 template <class S>
-void test40()
+TEST_CONSTEXPR_CXX20 void test40()
 {
     test(S("abcdefghijklmnopqrst"), 0, 20, S("abcde"), 0, 1, 19);
     test(S("abcdefghijklmnopqrst"), 0, 20, S("abcde"), 0, 2, 18);
@@ -4381,7 +4381,7 @@
 }
 
 template <class S>
-void test41()
+TEST_CONSTEXPR_CXX20 void test41()
 {
     test(S("abcdefghijklmnopqrst"), 0, 21, S("abcdefghij"), 0, 10, 10);
     test(S("abcdefghijklmnopqrst"), 0, 21, S("abcdefghij"), 0, 11, 10);
@@ -4486,7 +4486,7 @@
 }
 
 template <class S>
-void test42()
+TEST_CONSTEXPR_CXX20 void test42()
 {
     test(S("abcdefghijklmnopqrst"), 1, 0, S("abcdefghijklmnopqrst"), 1, 0, 0);
     test(S("abcdefghijklmnopqrst"), 1, 0, S("abcdefghijklmnopqrst"), 1, 1, -1);
@@ -4591,7 +4591,7 @@
 }
 
 template <class S>
-void test43()
+TEST_CONSTEXPR_CXX20 void test43()
 {
     test(S("abcdefghijklmnopqrst"), 1, 9, S("abcde"), 0, 6, 1);
     test(S("abcdefghijklmnopqrst"), 1, 9, S("abcde"), 1, 0, 9);
@@ -4696,7 +4696,7 @@
 }
 
 template <class S>
-void test44()
+TEST_CONSTEXPR_CXX20 void test44()
 {
     test(S("abcdefghijklmnopqrst"), 1, 18, S("abcdefghij"), 1, 4, 14);
     test(S("abcdefghijklmnopqrst"), 1, 18, S("abcdefghij"), 1, 8, 10);
@@ -4801,7 +4801,7 @@
 }
 
 template <class S>
-void test45()
+TEST_CONSTEXPR_CXX20 void test45()
 {
     test(S("abcdefghijklmnopqrst"), 1, 19, S("abcdefghijklmnopqrst"), 1, 19, 0);
     test(S("abcdefghijklmnopqrst"), 1, 19, S("abcdefghijklmnopqrst"), 1, 20, 0);
@@ -4906,7 +4906,7 @@
 }
 
 template <class S>
-void test46()
+TEST_CONSTEXPR_CXX20 void test46()
 {
     test(S("abcdefghijklmnopqrst"), 10, 0, S("abcde"), 1, 3, -3);
     test(S("abcdefghijklmnopqrst"), 10, 0, S("abcde"), 1, 4, -4);
@@ -5011,7 +5011,7 @@
 }
 
 template <class S>
-void test47()
+TEST_CONSTEXPR_CXX20 void test47()
 {
     test(S("abcdefghijklmnopqrst"), 10, 1, S("abcdefghij"), 5, 0, 1);
     test(S("abcdefghijklmnopqrst"), 10, 1, S("abcdefghij"), 5, 1, 5);
@@ -5116,7 +5116,7 @@
 }
 
 template <class S>
-void test48()
+TEST_CONSTEXPR_CXX20 void test48()
 {
     test(S("abcdefghijklmnopqrst"), 10, 5, S("abcdefghijklmnopqrst"), 10, 5, 0);
     test(S("abcdefghijklmnopqrst"), 10, 5, S("abcdefghijklmnopqrst"), 10, 9, -4);
@@ -5221,7 +5221,7 @@
 }
 
 template <class S>
-void test49()
+TEST_CONSTEXPR_CXX20 void test49()
 {
     test(S("abcdefghijklmnopqrst"), 10, 10, S("abcde"), 2, 1, 8);
     test(S("abcdefghijklmnopqrst"), 10, 10, S("abcde"), 2, 2, 8);
@@ -5326,7 +5326,7 @@
 }
 
 template <class S>
-void test50()
+TEST_CONSTEXPR_CXX20 void test50()
 {
     test(S("abcdefghijklmnopqrst"), 10, 11, S("abcdefghij"), 5, 5, 5);
     test(S("abcdefghijklmnopqrst"), 10, 11, S("abcdefghij"), 5, 6, 5);
@@ -5431,7 +5431,7 @@
 }
 
 template <class S>
-void test51()
+TEST_CONSTEXPR_CXX20 void test51()
 {
     test(S("abcdefghijklmnopqrst"), 19, 0, S("abcdefghijklmnopqrst"), 19, 0, 0);
     test(S("abcdefghijklmnopqrst"), 19, 0, S("abcdefghijklmnopqrst"), 19, 1, -1);
@@ -5536,7 +5536,7 @@
 }
 
 template <class S>
-void test52()
+TEST_CONSTEXPR_CXX20 void test52()
 {
     test(S("abcdefghijklmnopqrst"), 19, 2, S("abcde"), 4, 0, 1);
     test(S("abcdefghijklmnopqrst"), 19, 2, S("abcde"), 4, 1, 15);
@@ -5641,7 +5641,7 @@
 }
 
 template <class S>
-void test53()
+TEST_CONSTEXPR_CXX20 void test53()
 {
     test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghij"), 9, 2, -1);
     test(S("abcdefghijklmnopqrst"), 20, 0, S("abcdefghij"), 10, 0, 0);
@@ -5746,7 +5746,7 @@
 }
 
 template <class S>
-void test54()
+TEST_CONSTEXPR_CXX20 void test54()
 {
     test(S("abcdefghijklmnopqrst"), 20, 1, S("abcdefghijklmnopqrst"), 20, 1, 0);
     test(S("abcdefghijklmnopqrst"), 20, 1, S("abcdefghijklmnopqrst"), 21, 0, 0);
@@ -5827,7 +5827,7 @@
 }
 
 template<class S>
-void test55()
+TEST_CONSTEXPR_CXX20 void test55()
 {
     test_npos(S(""), 0, 0, S(""), 0, 0);
     test_npos(S(""), 0, 0, S("abcde"), 0, -5);
@@ -5836,10 +5836,8 @@
     test_npos(S("abcde"), 0, 0, S("abcdefghij"), 5, -5);
 }
 
-int main(int, char**)
-{
-    {
-    typedef std::string S;
+template<class S>
+TEST_CONSTEXPR_CXX20 bool test_0() {
     test0<S>();
     test1<S>();
     test2<S>();
@@ -5853,6 +5851,12 @@
     test10<S>();
     test11<S>();
     test12<S>();
+
+    return true;
+}
+
+template<class S>
+TEST_CONSTEXPR_CXX20 bool test_1() {
     test13<S>();
     test14<S>();
     test15<S>();
@@ -5865,68 +5869,14 @@
     test22<S>();
     test23<S>();
     test24<S>();
-    test25<S>();
-    test26<S>();
-    test27<S>();
-    test28<S>();
-    test29<S>();
-    test30<S>();
-    test31<S>();
-    test32<S>();
-    test33<S>();
-    test34<S>();
-    test35<S>();
-    test36<S>();
-    test37<S>();
-    test38<S>();
-    test39<S>();
-    test40<S>();
+
+    return true;
+}
+
+template<class S>
+TEST_CONSTEXPR_CXX20 bool test_2() {
     test41<S>();
     test42<S>();
-    test43<S>();
-    test44<S>();
-    test45<S>();
-    test46<S>();
-    test47<S>();
-    test48<S>();
-    test49<S>();
-    test50<S>();
-    test51<S>();
-    test52<S>();
-    test53<S>();
-    test54<S>();
-    test55<S>();
-    }
-#if TEST_STD_VER >= 11
-    {
-    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
-    test0<S>();
-    test1<S>();
-    test2<S>();
-    test3<S>();
-    test4<S>();
-    test5<S>();
-    test6<S>();
-    test7<S>();
-    test8<S>();
-    test9<S>();
-    test10<S>();
-    test11<S>();
-    test12<S>();
-    test13<S>();
-    test14<S>();
-    test15<S>();
-    test16<S>();
-    test17<S>();
-    test18<S>();
-    test19<S>();
-    test20<S>();
-    test21<S>();
-    test22<S>();
-    test23<S>();
-    test24<S>();
-    test25<S>();
-    test26<S>();
     test27<S>();
     test28<S>();
     test29<S>();
@@ -5937,6 +5887,12 @@
     test34<S>();
     test35<S>();
     test36<S>();
+
+    return true;
+}
+
+template<class S>
+TEST_CONSTEXPR_CXX20 bool test_3() {
     test37<S>();
     test38<S>();
     test39<S>();
@@ -5948,6 +5904,12 @@
     test45<S>();
     test46<S>();
     test47<S>();
+
+    return true;
+}
+
+template<class S>
+TEST_CONSTEXPR_CXX20 bool test_4() {
     test48<S>();
     test49<S>();
     test50<S>();
@@ -5956,7 +5918,47 @@
     test53<S>();
     test54<S>();
     test55<S>();
-    }
+
+    return true;
+}
+
+int main() {
+  {
+    typedef std::string S;
+    test_0<S>();
+    test_1<S>();
+    test_2<S>();
+    test_3<S>();
+    test_4<S>();
+  }
+#if TEST_STD_VER >= 11
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    test_0<S>();
+    test_1<S>();
+    test_2<S>();
+    test_3<S>();
+    test_4<S>();
+  }
+#endif
+
+#if TEST_STD_VER > 17
+  {
+    typedef std::string S;
+    static_assert(test_0<S>());
+    static_assert(test_1<S>());
+    static_assert(test_2<S>());
+    static_assert(test_3<S>());
+    static_assert(test_4<S>());
+  }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    static_assert(test_0<S>());
+    static_assert(test_1<S>());
+    static_assert(test_2<S>());
+    static_assert(test_3<S>());
+    static_assert(test_4<S>());
+  }
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp
@@ -18,7 +18,7 @@
 
 #include "test_macros.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -28,14 +28,14 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::size_type pos1, typename S::size_type n1,
      SV sv, int x)
 {
     if (pos1 <= s.size())
         assert(sign(s.compare(pos1, n1, sv)) == sign(x));
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -51,7 +51,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), 0, 0, SV(""), 0);
     test(S(""), 0, 0, SV("abcde"), -5);
@@ -156,7 +156,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), 6, 0, SV(""), 0);
     test(S("abcde"), 6, 0, SV("abcde"), 0);
@@ -261,7 +261,7 @@
 }
 
 template <class S, class SV>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcdefghijklmnopqrst"), 0, 0, SV(""), 0);
     test(S("abcdefghijklmnopqrst"), 0, 0, SV("abcde"), -5);
@@ -361,8 +361,7 @@
     test(S("abcdefghijklmnopqrst"), 21, 0, SV("abcdefghijklmnopqrst"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -379,6 +378,15 @@
     test2<S, SV>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp
@@ -16,7 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -26,15 +26,14 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, int x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.compare(str));
     assert(sign(s.compare(str)) == sign(x));
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), S(""), 0);
@@ -82,6 +81,15 @@
     assert(s.compare({"abc", 1}) < 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp
@@ -16,7 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 
-int sign(int x)
+TEST_CONSTEXPR_CXX20 int sign(int x)
 {
     if (x == 0)
         return 0;
@@ -26,15 +26,14 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, int x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.compare(sv));
     assert(sign(s.compare(sv)) == sign(x));
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -77,6 +76,15 @@
     test(S("abcdefghijklmnopqrst"), SV("abcdefghijklmnopqrst"), 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_not_of(c));
@@ -37,8 +37,7 @@
         assert(x < s.size());
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 'q', 0, S::npos);
@@ -101,6 +100,15 @@
     test(S("laenfsbridchgotmkqpj"), 'q', 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type x)
 {
     assert(s.find_first_not_of(str) == x);
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, S::npos);
     test(S(""), "laenf", 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), "", S::npos);
     test(S(""), "laenf", S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -156,6 +155,15 @@
     test1<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type n, typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0, S::npos);
     test(S(""), "irkhs", 0, 0, S::npos);
@@ -133,7 +133,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("gbhqo"), "skqne", 5, 4, S::npos);
     test(S("ktdor"), "kipnf", 5, 5, S::npos);
@@ -238,7 +238,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, S::npos);
     test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, S::npos);
@@ -343,7 +343,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, S::npos);
     test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, S::npos);
@@ -367,8 +367,7 @@
     test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -385,6 +384,15 @@
     test3<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_not_of(str, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_not_of(str));
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), S(""), 0, S::npos);
     test(S(""), S("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), S(""), S::npos);
     test(S(""), S("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     assert(s.find_first_not_of({"abc", 1}) == 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_of(c));
@@ -37,8 +37,7 @@
         assert(x < s.size());
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 'e', 0, S::npos);
@@ -97,6 +96,15 @@
     test(S("laenfsbridchgotmkqpj"), 'e', 2);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_of(str));
@@ -38,7 +38,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, S::npos);
     test(S(""), "laenf", 0, S::npos);
@@ -123,7 +123,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), "", S::npos);
     test(S(""), "laenf", S::npos);
@@ -143,8 +143,7 @@
     test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -157,6 +156,15 @@
     test1<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type n, typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0, S::npos);
     test(S(""), "irkhs", 0, 0, S::npos);
@@ -133,7 +133,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("gbhqo"), "skqne", 5, 4, S::npos);
     test(S("ktdor"), "kipnf", 5, 5, S::npos);
@@ -238,7 +238,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, S::npos);
     test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, S::npos);
@@ -343,7 +343,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, S::npos);
     test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, S::npos);
@@ -367,8 +367,7 @@
     test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -385,6 +384,15 @@
     test3<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_of(str, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_of(str));
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), S(""), 0, S::npos);
     test(S(""), S("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), S(""), S::npos);
     test(S(""), S("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     assert(s.find_first_of({"abc", 1}) == std::string::npos);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_of(sv, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_first_of(sv));
@@ -37,7 +37,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), SV(""), 0, S::npos);
     test(S(""), SV("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), SV(""), S::npos);
     test(S(""), SV("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -158,6 +157,15 @@
     test1<S, SV>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_not_of(c));
@@ -37,8 +37,7 @@
         assert(x < s.size());
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 'i', 0, S::npos);
@@ -97,6 +96,15 @@
     test(S("laenfsbridchgotmkqpj"), 'i', 19);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_not_of(str));
@@ -38,7 +38,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, S::npos);
     test(S(""), "laenf", 0, S::npos);
@@ -123,7 +123,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), "", S::npos);
     test(S(""), "laenf", S::npos);
@@ -143,8 +143,7 @@
     test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -157,6 +156,15 @@
     test1<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type n, typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0, S::npos);
     test(S(""), "irkhs", 0, 0, S::npos);
@@ -133,7 +133,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("gbhqo"), "skqne", 5, 4, 4);
     test(S("ktdor"), "kipnf", 5, 5, 4);
@@ -238,7 +238,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, 8);
     test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, 9);
@@ -343,7 +343,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, 19);
     test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, 19);
@@ -367,8 +367,7 @@
     test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -385,6 +384,15 @@
     test3<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_not_of(str, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_not_of(str));
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), S(""), 0, S::npos);
     test(S(""), S("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), S(""), S::npos);
     test(S(""), S("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     assert(s.find_last_not_of({"abc", 1}) == s.size() - 1);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_not_of(sv, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_not_of(sv));
@@ -37,7 +37,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), SV(""), 0, S::npos);
     test(S(""), SV("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), SV(""), S::npos);
     test(S(""), SV("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -158,6 +157,15 @@
 //     test1<S, SV>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_of(c));
@@ -37,8 +37,7 @@
         assert(x < s.size());
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 'm', 0, S::npos);
@@ -97,6 +96,15 @@
     test(S("laenfsbridchgotmkqpj"), 'm', 15);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_of(str));
@@ -38,7 +38,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, S::npos);
     test(S(""), "laenf", 0, S::npos);
@@ -123,7 +123,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), "", S::npos);
     test(S(""), "laenf", S::npos);
@@ -143,8 +143,7 @@
     test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", 19);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -157,6 +156,15 @@
     test1<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type n, typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0, S::npos);
     test(S(""), "irkhs", 0, 0, S::npos);
@@ -133,7 +133,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("gbhqo"), "skqne", 5, 4, 3);
     test(S("ktdor"), "kipnf", 5, 5, 0);
@@ -238,7 +238,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, 9);
     test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, 8);
@@ -343,7 +343,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, 4);
     test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, 17);
@@ -367,8 +367,7 @@
     test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, 19);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -385,6 +384,15 @@
     test3<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_of(str, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_of(str));
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), S(""), 0, S::npos);
     test(S(""), S("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), S(""), S::npos);
     test(S(""), S("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), 19);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     assert(s.find_last_of({"abc", 1}) == std::string::npos);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_of(sv, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find_last_of(sv));
@@ -37,7 +37,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), SV(""), 0, S::npos);
     test(S(""), SV("laenf"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), SV(""), S::npos);
     test(S(""), SV("laenf"), S::npos);
@@ -142,8 +142,7 @@
     test(S("pniotcfrhqsmgdkjbael"), SV("htaobedqikfplcgjsmrn"), 19);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -158,6 +157,15 @@
     test1<S, SV>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find(c));
@@ -37,8 +37,7 @@
         assert(0 <= x && x + 1 <= s.size());
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 'c', 0, S::npos);
@@ -97,6 +96,15 @@
     test(S("abcdeabcdeabcdeabcde"), 'c', 2);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -31,7 +31,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find(str));
@@ -44,7 +44,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0);
     test(S(""), "abcde", 0, S::npos);
@@ -129,7 +129,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), "", 0);
     test(S(""), "abcde", S::npos);
@@ -149,8 +149,7 @@
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     test1<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type n, typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0, 0);
     test(S(""), "abcde", 0, 0, 0);
@@ -133,7 +133,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), "abcde", 5, 4, S::npos);
     test(S("abcde"), "abcde", 5, 5, S::npos);
@@ -238,7 +238,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcdeabcde"), "abcdeabcde", 10, 5, S::npos);
     test(S("abcdeabcde"), "abcdeabcde", 10, 9, S::npos);
@@ -343,7 +343,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 1, S::npos);
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 10, S::npos);
@@ -367,8 +367,7 @@
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 20, S::npos);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -385,6 +384,15 @@
     test3<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find(str, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find(str));
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), S(""), 0, 0);
     test(S(""), S("abcde"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), S(""), 0);
     test(S(""), S("abcde"), S::npos);
@@ -142,8 +142,7 @@
     test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     assert(s.find({"abc", 1}) == std::string::npos);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find(sv, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.find(sv));
@@ -37,7 +37,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), SV(""), 0, 0);
     test(S(""), SV("abcde"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), SV(""), 0);
     test(S(""), SV("abcde"), S::npos);
@@ -142,8 +142,7 @@
     test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -158,6 +157,15 @@
     test1<S, SV>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::value_type c, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.rfind(c));
@@ -37,8 +37,7 @@
         assert(x + 1 <= s.size());
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 'b', 0, S::npos);
@@ -97,6 +96,15 @@
     test(S("abcdeabcdeabcdeabcde"), 'b', 16);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
      typename S::size_type x)
 {
@@ -31,7 +31,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.rfind(str));
@@ -45,7 +45,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0);
     test(S(""), "abcde", 0, S::npos);
@@ -130,7 +130,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), "", 0);
     test(S(""), "abcde", S::npos);
@@ -150,8 +150,7 @@
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -164,6 +163,15 @@
     test1<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const typename S::value_type* str, typename S::size_type pos,
       typename S::size_type n, typename S::size_type x)
 {
@@ -28,7 +28,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), "", 0, 0, 0);
     test(S(""), "abcde", 0, 0, 0);
@@ -133,7 +133,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S("abcde"), "abcde", 5, 4, 0);
     test(S("abcde"), "abcde", 5, 5, 0);
@@ -238,7 +238,7 @@
 }
 
 template <class S>
-void test2()
+TEST_CONSTEXPR_CXX20 void test2()
 {
     test(S("abcdeabcde"), "abcdeabcde", 10, 5, 5);
     test(S("abcdeabcde"), "abcdeabcde", 10, 9, 0);
@@ -343,7 +343,7 @@
 }
 
 template <class S>
-void test3()
+TEST_CONSTEXPR_CXX20 void test3()
 {
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 1, 15);
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 10, 10);
@@ -367,8 +367,7 @@
     test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 20, 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -385,6 +384,15 @@
     test3<S>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.rfind(str, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, const S& str, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.rfind(str));
@@ -37,7 +37,7 @@
 }
 
 template <class S>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), S(""), 0, 0);
     test(S(""), S("abcde"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), S(""), 0);
     test(S(""), S("abcde"), S::npos);
@@ -142,8 +142,7 @@
     test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test0<S>();
@@ -163,6 +162,15 @@
     assert(s.rfind({"abc", 1}) == std::string::npos);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp
@@ -17,7 +17,7 @@
 #include "min_allocator.h"
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.rfind(sv, pos));
@@ -27,7 +27,7 @@
 }
 
 template <class S, class SV>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, SV sv, typename S::size_type x)
 {
     LIBCPP_ASSERT_NOEXCEPT(s.rfind(sv));
@@ -37,7 +37,7 @@
 }
 
 template <class S, class SV>
-void test0()
+TEST_CONSTEXPR_CXX20 void test0()
 {
     test(S(""), SV(""), 0, 0);
     test(S(""), SV("abcde"), 0, S::npos);
@@ -122,7 +122,7 @@
 }
 
 template <class S, class SV>
-void test1()
+TEST_CONSTEXPR_CXX20 void test1()
 {
     test(S(""), SV(""), 0);
     test(S(""), SV("abcde"), S::npos);
@@ -142,8 +142,7 @@
     test(S("abcdeabcdeabcdeabcde"), SV("abcdeabcdeabcdeabcde"), 0);
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     typedef std::string_view SV;
@@ -158,6 +157,15 @@
     test1<S, SV>();
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp
@@ -19,7 +19,7 @@
 #include "min_allocator.h"
 
 template <class S>
-void
+TEST_CONSTEXPR_CXX20 void
 test(const S& s, typename S::size_type pos, typename S::size_type n)
 {
     if (pos <= s.size())
@@ -32,7 +32,7 @@
         assert(S::traits_type::compare(s.data()+pos, str.data(), rlen) == 0);
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    else
+    else if (!TEST_IS_CONSTANT_EVALUATED)
     {
         try
         {
@@ -47,8 +47,7 @@
 #endif
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test(S(""), 0, 0);
@@ -173,6 +172,15 @@
     test(S("dplqartnfgejichmoskb"), 21, 0);
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp b/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp
@@ -19,14 +19,13 @@
 
 
 template <class C>
-void test_contiguous ( const C &c )
+TEST_CONSTEXPR_CXX20 void test_contiguous ( const C &c )
 {
     for ( size_t i = 0; i < c.size(); ++i )
         assert ( *(c.begin() + static_cast<typename C::difference_type>(i)) == *(std::addressof(*c.begin()) + i));
 }
 
-int main(int, char**)
-{
+TEST_CONSTEXPR_CXX20 bool test() {
     {
     typedef std::string S;
     test_contiguous(S());
@@ -50,6 +49,15 @@
     test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()));
     }
 #endif
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp b/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.char.pass.cpp
@@ -16,9 +16,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test() {
+  {
     typedef std::string S;
     S  s1 {};
     S  s2 { "abcde", 5 };
@@ -30,6 +29,15 @@
     assert ( s2.starts_with('a'));
     assert (!s2.starts_with('x'));
     }
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp b/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.ptr.pass.cpp
@@ -16,9 +16,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test() {
+  {
     typedef std::string S;
     const char *s = "abcde";
     S  s0 {};
@@ -58,6 +57,15 @@
     assert (!sNot.starts_with("abcde"));
     assert ( sNot.starts_with("def"));
     }
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp
--- a/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.starts_with/starts_with.string_view.pass.cpp
@@ -16,9 +16,8 @@
 
 #include "test_macros.h"
 
-int main(int, char**)
-{
-    {
+TEST_CONSTEXPR_CXX20 bool test() {
+  {
     typedef std::string S;
     typedef std::string_view SV;
     const char *s = "abcde";
@@ -67,7 +66,16 @@
     assert (!sNot.starts_with(sv4));
     assert (!sNot.starts_with(sv5));
     assert ( sNot.starts_with(svNot));
-    }
+  }
+    
+  return true;
+}
+
+int main() {
+  test();
+#if TEST_STD_VER > 17
+  static_assert(test());
+#endif
 
   return 0;
 }
diff --git a/libcxx/test/support/iterator_traits_cpp17_iterators.h b/libcxx/test/support/iterator_traits_cpp17_iterators.h
--- a/libcxx/test/support/iterator_traits_cpp17_iterators.h
+++ b/libcxx/test/support/iterator_traits_cpp17_iterators.h
@@ -9,6 +9,7 @@
 #ifndef TEST_SUPPORT_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS
 #define TEST_SUPPORT_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS
 
+#include "test_macros.h"
 struct iterator_traits_cpp17_iterator {
   int& operator*();
   iterator_traits_cpp17_iterator& operator++();
@@ -27,11 +28,11 @@
   using difference_type = int;
   using value_type = long;
 
-  int& operator*();
-  iterator_traits_cpp17_input_iterator& operator++();
-  iterator_traits_cpp17_input_iterator operator++(int);
+  TEST_CONSTEXPR_CXX20 int& operator*();
+  TEST_CONSTEXPR_CXX20 iterator_traits_cpp17_input_iterator& operator++();
+  TEST_CONSTEXPR_CXX20 iterator_traits_cpp17_input_iterator operator++(int);
 
-  bool operator==(iterator_traits_cpp17_input_iterator const&) const;
+  TEST_CONSTEXPR_CXX20 bool operator==(iterator_traits_cpp17_input_iterator const&) const;
 };
 
 struct iterator_traits_cpp17_proxy_input_iterator {
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -457,14 +457,14 @@
 
     enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
 
-    ThrowingIterator()
+    TEST_CONSTEXPR_CXX14 ThrowingIterator()
         : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {}
-    explicit ThrowingIterator(const T *first, const T *last, int index = 0, ThrowingAction action = TADereference)
+    TEST_CONSTEXPR_CXX14 explicit ThrowingIterator(const T *first, const T *last, int index = 0, ThrowingAction action = TADereference)
         : begin_(first), end_(last), current_(first), action_(action), index_(index) {}
-    ThrowingIterator(const ThrowingIterator &rhs)
+    TEST_CONSTEXPR_CXX14 ThrowingIterator(const ThrowingIterator &rhs)
         : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {}
 
-    ThrowingIterator& operator=(const ThrowingIterator& rhs) {
+    TEST_CONSTEXPR_CXX14 ThrowingIterator& operator=(const ThrowingIterator& rhs) {
         if (action_ == TAAssignment && --index_ < 0) {
 #ifndef TEST_HAS_NO_EXCEPTIONS
             throw std::runtime_error("throw from iterator assignment");
@@ -480,7 +480,7 @@
         return *this;
     }
 
-    reference operator*() const {
+    TEST_CONSTEXPR_CXX14 reference operator*() const {
         if (action_ == TADereference && --index_ < 0) {
 #ifndef TEST_HAS_NO_EXCEPTIONS
             throw std::runtime_error("throw from iterator dereference");
@@ -491,7 +491,7 @@
         return *current_;
     }
 
-    ThrowingIterator& operator++() {
+    TEST_CONSTEXPR_CXX14 ThrowingIterator& operator++() {
         if (action_ == TAIncrement && --index_ < 0) {
 #ifndef TEST_HAS_NO_EXCEPTIONS
             throw std::runtime_error("throw from iterator increment");
@@ -503,13 +503,13 @@
         return *this;
     }
 
-    ThrowingIterator operator++(int) {
+    TEST_CONSTEXPR_CXX14 ThrowingIterator operator++(int) {
         ThrowingIterator temp = *this;
         ++(*this);
         return temp;
     }
 
-    ThrowingIterator& operator--() {
+    TEST_CONSTEXPR_CXX14 ThrowingIterator& operator--() {
         if (action_ == TADecrement && --index_ < 0) {
 #ifndef TEST_HAS_NO_EXCEPTIONS
             throw std::runtime_error("throw from iterator decrement");
@@ -521,13 +521,13 @@
         return *this;
     }
 
-    ThrowingIterator operator--(int) {
+    TEST_CONSTEXPR_CXX14 ThrowingIterator operator--(int) {
         ThrowingIterator temp = *this;
         --(*this);
         return temp;
     }
 
-    friend bool operator==(const ThrowingIterator& a, const ThrowingIterator& b) {
+    TEST_CONSTEXPR_CXX14 friend bool operator==(const ThrowingIterator& a, const ThrowingIterator& b) {
         if (a.action_ == TAComparison && --a.index_ < 0) {
 #ifndef TEST_HAS_NO_EXCEPTIONS
             throw std::runtime_error("throw from iterator comparison");
@@ -542,7 +542,7 @@
         return a.current_ == b.current_;
     }
 
-    friend bool operator!=(const ThrowingIterator& a, const ThrowingIterator& b) {
+    TEST_CONSTEXPR_CXX14 friend bool operator!=(const ThrowingIterator& a, const ThrowingIterator& b) {
         return !(a == b);
     }
 
diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -10,6 +10,8 @@
 #ifndef SUPPORT_TEST_MACROS_HPP
 #define SUPPORT_TEST_MACROS_HPP
 
+#include <version>
+
 // Attempt to get STL specific macros like _LIBCPP_VERSION using the most
 // minimal header possible. If we're testing libc++, we should use `<__config>`.
 // If <__config> isn't available, fall back to <ciso646>.
@@ -145,6 +147,12 @@
 # define TEST_THROW_SPEC(...) throw(__VA_ARGS__)
 #endif
 
+#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
+#  define TEST_IS_CONSTANT_EVALUATED std::is_constant_evaluated()
+#else
+#  define TEST_IS_CONSTANT_EVALUATED false
+#endif
+
 #if TEST_STD_VER >= 14
 # define TEST_CONSTEXPR_CXX14 constexpr
 #else