[libcxx-commits] [libcxx] [libc++] Fix uninitialized algorithms when using unconstrained comparison operators (PR #69373)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 17 13:43:24 PDT 2023


================
@@ -44,26 +44,23 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// This is a simplified version of C++20 `unreachable_sentinel` that doesn't use concepts and thus can be used in any
-// language mode.
-struct __unreachable_sentinel {
-  template <class _Iter>
-  _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool operator!=(const _Iter&, __unreachable_sentinel) _NOEXCEPT {
-    return true;
+struct __always_false {
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(_Args&&...) const _NOEXCEPT {
+    return false;
   }
 };
 
 // uninitialized_copy
 
-template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2>
-inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator>
-__uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast,
-                     _ForwardIterator __ofirst, _Sentinel2 __olast) {
+template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _OutputIterCompare>
+inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> __uninitialized_copy(
+    _InputIterator __ifirst, _Sentinel1 __ilast, _ForwardIterator __ofirst, _OutputIterCompare __out_iter_at_end) {
   _ForwardIterator __idx = __ofirst;
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
   try {
 #endif
-    for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx)
+    for (; __ifirst != __ilast && !__out_iter_at_end(__idx); ++__ifirst, (void)++__idx)
----------------
phyBrackets wrote:

Help me in understand, I wonder previously `__unreachable_sentinel`, when compared against any iterator, this sentinel believe that the iterator hasn't reached the end. In the new case `__always_false`  always returns false, meaning the output iterator is never considered to be at its end. Is there anything to worry about the semantics here as compare to previous version? I am not sure, although the fundamental behavior is indeed seems same in both cases 🤔

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


More information about the libcxx-commits mailing list