[llvm-bugs] [Bug 52151] New: std::search violates random access iterator concept by not using the iterator's difference_type
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Oct 12 01:48:52 PDT 2021
https://bugs.llvm.org/show_bug.cgi?id=52151
Bug ID: 52151
Summary: std::search violates random access iterator concept by
not using the iterator's difference_type
Product: libc++
Version: 12.0
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: All Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: dangelog at gmail.com
CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com
Hi,
The std::search implementation for random access iterators performs a couple of
sums between an iterator of the first range and an integral quantity of an
"arbitrary" integer type (the difference_type of the iterator of the *second*
range):
https://github.com/llvm/llvm-project/blob/main/libcxx/include/__algorithm/search.h#L71
typedef typename iterator_traits<_RandomAccessIterator1>::difference_type
_D1;
typedef typename iterator_traits<_RandomAccessIterator2>::difference_type
_D2;
const _D2 __len2 = __last2 - __first2;
const _RandomAccessIterator1 __s = __last1 - (__len2 - 1);
return _VSTD::make_pair(__first1, __first1 + __len2);
(Nitpicking, __len2 - 1 could also be a type different from _D2, due to integer
promotions and what not.)
Anyways, the problem is that this is illegal: random access iterators can only
be summed with their own difference_type, not with an arbitrary integer. The
solution here would simply be to add a couple of casts/conversions to _D1
before doing the sum.
--
As of why I ended up noticing this: in Qt 6, for a lot of wrong reasons that
I'm trying to fix, we have QVector's iterators which are implicitly convertible
to a raw pointer (because in Qt 5 the iterators _were_ raw pointers, so this is
a band-aid measure to avoid breaking source compatibility).
The difference type is "qsizetype", a signed 32/64 bits integer type.
This means that now one has something like this:
template <typename T>
class QVector {
class iterator {
using difference_type = qsizetype;
/* implicit */ operator T*() const;
iterator operator+(qsizetype) const;
}
};
The problem with this setup is that if you apply operator+ to an iterator
object and some integer type other than qsizetype (e.g. int, ptrdiff_t, ...)
then the call becomes ambiguous; it + 42 could either be
operator+(iterator, int converted to qsizetype)
or
operator+(iterator converted to raw pointer, int)
and clang errors out. This is what this bug report is about.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20211012/40d5e621/attachment.html>
More information about the llvm-bugs
mailing list