[llvm] r207743 - [LCG] Fix a bad bug in the new fancy iterator scheme I added to support
David Blaikie
dblaikie at gmail.com
Thu May 1 10:18:28 PDT 2014
On Thu, May 1, 2014 at 3:41 AM, Chandler Carruth <chandlerc at gmail.com> wrote:
> Author: chandlerc
> Date: Thu May 1 05:41:51 2014
> New Revision: 207743
>
> URL: http://llvm.org/viewvc/llvm-project?rev=207743&view=rev
> Log:
> [LCG] Fix a bad bug in the new fancy iterator scheme I added to support
> removal. We can't just blindly increment (or decrement) the adapted
> iterator when the value is null because doing so can walk past the end
> (or beginning) and keep inspecting the value. The fix I've implemented
> is to restrict this further to a forward iterator and add an end
> iterator to the members (replacing a member that had become dead when
> I switched to the adaptor base!) and using that to stop the iteration.
>
> I'm not entirely pleased with this solution. I feel like forward
> iteration is too restrictive. I wasn't even happy about bidirectional
> iteration. It also makes the iterator objects larger and the iteration
> loops more complex. However, I also don't really like the other
> alternative that seems obvious: a sentinel node. I'm still hoping to
> come up with a more elegant solution here, but this at least fixes the
> MSan and Valgrind errors on this code.
I hadn't noticed before, but it looks like you have a filtering
iterator - again, would be nice to have that as a generic abstraction
at some point. I know we have more than a few (specific_decl_iterator
in Clang, to name one off the top of my head) cases of this.
(& FWIW, http://blogs.msdn.com/b/vcblog/archive/2010/08/09/the-filterator.aspx
discusses how to write one and chooses the "store the current and end
iterator in the filtering iterator" strategy - there's no other
general solution, really)
>
> Modified:
> llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
>
> Modified: llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyCallGraph.h?rev=207743&r1=207742&r2=207743&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/LazyCallGraph.h (original)
> +++ llvm/trunk/include/llvm/Analysis/LazyCallGraph.h Thu May 1 05:41:51 2014
> @@ -115,17 +115,18 @@ public:
> /// the graph.
> class iterator
> : public iterator_adaptor_base<iterator, NodeVectorImplT::iterator,
> - std::bidirectional_iterator_tag, Node> {
> + std::forward_iterator_tag, Node> {
> friend class LazyCallGraph;
> friend class LazyCallGraph::Node;
>
> LazyCallGraph *G;
> - NodeVectorImplT::iterator NI;
> + NodeVectorImplT::iterator E;
>
> // Build the iterator for a specific position in a node list.
> - iterator(LazyCallGraph &G, NodeVectorImplT::iterator NI)
> - : iterator_adaptor_base(NI), G(&G) {
> - while (I->isNull())
> + iterator(LazyCallGraph &G, NodeVectorImplT::iterator NI,
> + NodeVectorImplT::iterator E)
> + : iterator_adaptor_base(NI), G(&G), E(E) {
> + while (I != E && I->isNull())
> ++I;
> }
>
> @@ -136,15 +137,7 @@ public:
> iterator &operator++() {
> do {
> ++I;
> - } while (I->isNull());
> - return *this;
> - }
> -
> - using iterator_adaptor_base::operator--;
> - iterator &operator--() {
> - do {
> - --I;
> - } while (I->isNull());
> + } while (I != E && I->isNull());
> return *this;
> }
>
> @@ -199,8 +192,10 @@ public:
> return F;
> };
>
> - iterator begin() const { return iterator(*G, Callees.begin()); }
> - iterator end() const { return iterator(*G, Callees.end()); }
> + iterator begin() const {
> + return iterator(*G, Callees.begin(), Callees.end());
> + }
> + iterator end() const { return iterator(*G, Callees.end(), Callees.end()); }
>
> /// Equality is defined as address equality.
> bool operator==(const Node &N) const { return this == &N; }
> @@ -358,8 +353,10 @@ public:
> LazyCallGraph(LazyCallGraph &&G);
> LazyCallGraph &operator=(LazyCallGraph &&RHS);
>
> - iterator begin() { return iterator(*this, EntryNodes.begin()); }
> - iterator end() { return iterator(*this, EntryNodes.end()); }
> + iterator begin() {
> + return iterator(*this, EntryNodes.begin(), EntryNodes.end());
> + }
> + iterator end() { return iterator(*this, EntryNodes.end(), EntryNodes.end()); }
>
> postorder_scc_iterator postorder_scc_begin() {
> return postorder_scc_iterator(*this);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list