ADT: Require explicit ilist iterator/pointer conversions

Disallow implicit conversions between ilist iterators and element
points.  Explicit conversions still work of course.

This is the first step toward removing the undefined behaviour in
`ilist` and `iplist`:
http://lists.llvm.org/pipermail/llvm-dev/2015-October/091115.html

The motivation for removing the implicit iterators is that I came across
real bugs (that were *really* getting lucky).  More details and some
brief discussion later in that thread:
http://lists.llvm.org/pipermail/llvm-dev/2015-October/091617.html

Note: if you have out-of-tree code, it should be fairly easy to revert
this patch downstream while you update your out-of-tree call sites.
Note that these conversions are occasionally latent bugs (that may
happen to "work" now, but only because of getting lucky with UB;
follow-ups will change your luck).  When they are valid, I suggest using
`->getIterator()` to go from pointer to iterator, and `&*` to go from
iterator to pointer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252372 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-11-07 00:02:32 +00:00
parent 5013c51dfc
commit 84cb8974bd

View File

@ -220,8 +220,8 @@ private:
template<class T> void operator-(T) const; template<class T> void operator-(T) const;
public: public:
ilist_iterator(pointer NP) : NodePtr(NP) {} explicit ilist_iterator(pointer NP) : NodePtr(NP) {}
ilist_iterator(reference NR) : NodePtr(&NR) {} explicit ilist_iterator(reference NR) : NodePtr(&NR) {}
ilist_iterator() : NodePtr(nullptr) {} ilist_iterator() : NodePtr(nullptr) {}
// This is templated so that we can allow constructing a const iterator from // This is templated so that we can allow constructing a const iterator from
@ -241,7 +241,7 @@ public:
void reset(pointer NP) { NodePtr = NP; } void reset(pointer NP) { NodePtr = NP; }
// Accessors... // Accessors...
operator pointer() const { explicit operator pointer() const {
return NodePtr; return NodePtr;
} }