[libcxx-commits] [PATCH] D130538: [libc++] Fix `_IterOps::__iter_move` returning a dangling reference for non-conforming iterators.

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 26 11:42:14 PDT 2022


ldionne requested changes to this revision.
ldionne added a comment.
This revision now requires changes to proceed.

I like this new approach regardless of the issues raised in D129823 <https://reviews.llvm.org/D129823> because it is closer to `decltype(auto)`, and that's what we're trying to achieve at the end of the day.

However, the truth is that any iterator that lies about its `iterator_traits::reference` is a potential issue just waiting to explode, and since we can easily diagnose it, I think we should. That's why I've suggested adding a `static_assert` as a QOI thing.

Is it going to break some code? Probably, but that will actually point out potential bugs in people's code, which is a nice property to have.



================
Comment at: libcxx/include/__algorithm/iterator_operations.h:68
+  template <class _Iter>
+  using __deref_t = decltype(*std::declval<_Iter>());
+
----------------
This way, we'll match the definition of `iter_reference_t`.


================
Comment at: libcxx/include/__algorithm/iterator_operations.h:71
+  template <class _Iter>
+  using __move_t = decltype(std::move(std::declval<__deref_t<_Iter> >()));
+
----------------
IMO that's easier to read, since I don't have to substitute `__deref_t` in my head and work through the additional `declval<T>()` layer.


================
Comment at: libcxx/include/__algorithm/iterator_operations.h:77-80
+  // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it.
+  // Note that we can't rely on `iterator_traits` because those might be invalid. While that makes the user code
+  // non-conforming, it wouldn't be visible if the implementation used `foo = std::move(*iter);` rather than
+  // `foo = _IterOps<_Policy>::__iter_move(iter)`.
----------------



================
Comment at: libcxx/include/__algorithm/iterator_operations.h:84-85
+      __move_t<_Iter> >
+  __iter_move(_Iter&& __i) {
     return std::move(*std::forward<_Iter>(__i));
   }
----------------
(suggested message, feel free to change)

The full link is http://eel.is/c++draft/input.iterators#tab:inputiterator.

Also, please add a libc++ specific test to ensure that we do trigger the `static_assert` at least when we call `std::sort` with a mis-behaving iterator.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130538/new/

https://reviews.llvm.org/D130538



More information about the libcxx-commits mailing list