From: Argyrios Kyrtzidis Date: Sat, 17 Dec 2011 04:13:25 +0000 (+0000) Subject: Add a sanity check in the Redeclarable::redecl_iterator to avoid infinite loop X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=672b3232f7b0cc5dc024a7702be1a26885fdea57;p=clang Add a sanity check in the Redeclarable::redecl_iterator to avoid infinite loop when we formed an invalid redeclaration chain due to a bug. Thanks to Doug for the hint! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146816 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index e87ca78d63..c223d768c6 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -116,6 +116,7 @@ public: /// Current - The current declaration. decl_type *Current; decl_type *Starter; + bool PassedFirst; public: typedef decl_type* value_type; @@ -125,13 +126,24 @@ public: typedef std::ptrdiff_t difference_type; redecl_iterator() : Current(0) { } - explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) { } + explicit redecl_iterator(decl_type *C) + : Current(C), Starter(C), PassedFirst(false) { } reference operator*() const { return Current; } pointer operator->() const { return Current; } redecl_iterator& operator++() { assert(Current && "Advancing while iterator has reached end"); + // Sanity check to avoid infinite loop on invalid redecl chain. + if (Current->isFirstDeclaration()) { + if (PassedFirst) { + assert(0 && "Passed first decl twice, invalid redecl chain!"); + Current = 0; + return *this; + } + PassedFirst = true; + } + // Get either previous decl or latest decl. decl_type *Next = Current->RedeclLink.getNext(); Current = (Next != Starter ? Next : 0);