[libcxx-commits] [PATCH] D60592: [libc++] Fix build failure with _LIBCPP_DEBUG=0 when iterators return values instead of references
Tom Anderson via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Apr 11 17:25:56 PDT 2019
thomasanderson created this revision.
thomasanderson added a reviewer: EricWF.
Herald added subscribers: jdoerfert, ldionne, christof.
thomasanderson added a comment.
@EricWF ptal. I think this regressed after https://reviews.llvm.org/rCXX355752
There are many STL algorithms (such as lexicographical_compare) that compare
values pointed to by iterators like so:
__comp(*it1, *it2);
When building with `_LIBCPP_DEBUG=0`, comparators are wrapped in `__debug_less`
which does some additional validation. But `__debug_less::operator()` takes
non-const references, so if the type of `*it1` is int, not int&, then the build
will fail.
This change adds a `const&` overload for `operator()` to fix the build.
Repository:
rCXX libc++
https://reviews.llvm.org/D60592
Files:
libcxx/include/algorithm
libcxx/test/libcxx/algorithms/debug_less.pass.cpp
Index: libcxx/test/libcxx/algorithms/debug_less.pass.cpp
===================================================================
--- libcxx/test/libcxx/algorithms/debug_less.pass.cpp
+++ libcxx/test/libcxx/algorithms/debug_less.pass.cpp
@@ -235,10 +235,33 @@
}
}
+struct ValueIterator {
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = size_t;
+ using difference_type = ptrdiff_t;
+ using reference = size_t&;
+ using pointer = size_t*;
+
+ ValueIterator() = default;
+
+ value_type operator*() { return 0; }
+ ValueIterator& operator++() { return *this; }
+
+ friend bool operator==(ValueIterator, ValueIterator) { return true; }
+ friend bool operator!=(ValueIterator, ValueIterator) { return false; }
+};
+
+void test_value_iterator() {
+ // Ensure no build failures when iterators return values, not references.
+ assert(0 == std::lexicographical_compare(ValueIterator{}, ValueIterator{},
+ ValueIterator{}, ValueIterator{}));
+}
+
int main(int, char**) {
test_passing();
test_failing();
test_upper_and_lower_bound();
test_non_const_arg_cmp();
+ test_value_iterator();
return 0;
}
Index: libcxx/include/algorithm
===================================================================
--- libcxx/include/algorithm
+++ libcxx/include/algorithm
@@ -783,6 +783,15 @@
_Compare __comp_;
__debug_less(_Compare& __c) : __comp_(__c) {}
+ template <class _Tp, class _Up>
+ bool operator()(const _Tp& __x, const _Up& __y)
+ {
+ bool __r = __comp_(__x, __y);
+ if (__r)
+ __do_compare_assert(0, __y, __x);
+ return __r;
+ }
+
template <class _Tp, class _Up>
bool operator()(_Tp& __x, _Up& __y)
{
@@ -792,6 +801,15 @@
return __r;
}
+ template <class _LHS, class _RHS>
+ inline _LIBCPP_INLINE_VISIBILITY
+ decltype((void)_VSTD::declval<_Compare&>()(
+ _VSTD::declval<const _LHS &>(), _VSTD::declval<const _RHS &>()))
+ __do_compare_assert(int, const _LHS & __l, const _RHS & __r) {
+ _LIBCPP_ASSERT(!__comp_(__l, __r),
+ "Comparator does not induce a strict weak ordering");
+ }
+
template <class _LHS, class _RHS>
inline _LIBCPP_INLINE_VISIBILITY
decltype((void)_VSTD::declval<_Compare&>()(
@@ -801,6 +819,10 @@
"Comparator does not induce a strict weak ordering");
}
+ template <class _LHS, class _RHS>
+ inline _LIBCPP_INLINE_VISIBILITY
+ void __do_compare_assert(long, const _LHS &, const _RHS &) {}
+
template <class _LHS, class _RHS>
inline _LIBCPP_INLINE_VISIBILITY
void __do_compare_assert(long, _LHS &, _RHS &) {}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60592.194788.patch
Type: text/x-patch
Size: 2739 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190412/17dfc5ad/attachment-0001.bin>
More information about the libcxx-commits
mailing list