<div dir="ltr">Build error here: <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/24265/steps/build%20release%20tsan%20with%20clang/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/24265/steps/build%20release%20tsan%20with%20clang/logs/stdio</a></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Aug 22, 2016 at 3:29 PM Duncan P. N. Exon Smith via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br>
Date: Mon Aug 22 17:21:07 2016<br>
New Revision: 279484<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=279484&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=279484&view=rev</a><br>
Log:<br>
ADT: Separate some list manipulation API into ilist_base, NFC<br>
<br>
Separate algorithms in iplist<T> that don't depend on T into ilist_base,<br>
and unit test them.<br>
<br>
While I was adding unit tests for these algorithms anyway, I also added<br>
unit tests for ilist_node_base and ilist_sentinel<T>.<br>
<br>
To make the algorithms and unit tests easier to write, I also did the<br>
following minor changes as a drive-by:<br>
- encapsulate Prev/Next in ilist_node_base to so that algorithms are<br>
  easier to read, and<br>
- update ilist_node_access API to take nodes by reference.<br>
<br>
There should be no real functionality change here.<br>
<br>
Added:<br>
    llvm/trunk/unittests/ADT/IListBaseTest.cpp<br>
    llvm/trunk/unittests/ADT/IListNodeBaseTest.cpp<br>
    llvm/trunk/unittests/ADT/IListSentinelTest.cpp<br>
Modified:<br>
    llvm/trunk/include/llvm/ADT/ilist.h<br>
    llvm/trunk/include/llvm/ADT/ilist_node.h<br>
    llvm/trunk/unittests/ADT/CMakeLists.txt<br>
<br>
Modified: llvm/trunk/include/llvm/ADT/ilist.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist.h?rev=279484&r1=279483&r2=279484&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist.h?rev=279484&r1=279483&r2=279484&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ADT/ilist.h (original)<br>
+++ llvm/trunk/include/llvm/ADT/ilist.h Mon Aug 22 17:21:07 2016<br>
@@ -50,30 +50,19 @@ struct ilist_node_access {<br>
     return N;<br>
   }<br>
<br>
-  template <typename T> static ilist_node<T> *getPrev(ilist_node<T> *N) {<br>
-    return N->getPrev();<br>
+  template <typename T> static ilist_node<T> *getPrev(ilist_node<T> &N) {<br>
+    return N.getPrev();<br>
   }<br>
-  template <typename T> static ilist_node<T> *getNext(ilist_node<T> *N) {<br>
-    return N->getNext();<br>
+  template <typename T> static ilist_node<T> *getNext(ilist_node<T> &N) {<br>
+    return N.getNext();<br>
   }<br>
-  template <typename T> static const ilist_node<T> *getPrev(const ilist_node<T> *N) {<br>
-    return N->getPrev();<br>
-  }<br>
-  template <typename T> static const ilist_node<T> *getNext(const ilist_node<T> *N) {<br>
-    return N->getNext();<br>
-  }<br>
-<br>
-  template <typename T> static void setPrev(ilist_node<T> *N, ilist_node<T> *Prev) {<br>
-    N->setPrev(Prev);<br>
-  }<br>
-  template <typename T> static void setNext(ilist_node<T> *N, ilist_node<T> *Next) {<br>
-    N->setNext(Next);<br>
-  }<br>
-  template <typename T> static void setPrev(ilist_node<T> *N, std::nullptr_t) {<br>
-    N->setPrev(nullptr);<br>
-  }<br>
-  template <typename T> static void setNext(ilist_node<T> *N, std::nullptr_t) {<br>
-    N->setNext(nullptr);<br>
+  template <typename T><br>
+  static const ilist_node<T> *getPrev(const ilist_node<T> &N) {<br>
+    return N.getPrev();<br>
+  }<br>
+  template <typename T><br>
+  static const ilist_node<T> *getNext(const ilist_node<T> &N) {<br>
+    return N.getNext();<br>
   }<br>
 };<br>
<br>
@@ -228,12 +217,12 @@ public:<br>
<br>
   // Increment and decrement operators...<br>
   ilist_iterator &operator--() {<br>
-    NodePtr = ilist_node_access::getPrev(NodePtr);<br>
+    NodePtr = ilist_node_access::getPrev(*NodePtr);<br>
     assert(NodePtr && "--'d off the beginning of an ilist!");<br>
     return *this;<br>
   }<br>
   ilist_iterator &operator++() {<br>
-    NodePtr = ilist_node_access::getNext(NodePtr);<br>
+    NodePtr = ilist_node_access::getNext(*NodePtr);<br>
     return *this;<br>
   }<br>
   ilist_iterator operator--(int) {<br>
@@ -271,6 +260,64 @@ template<typename NodeTy> struct simplif<br>
   }<br>
 };<br>
<br>
+/// Implementations of list algorithms using ilist_node_base.<br>
+class ilist_base {<br>
+public:<br>
+  static void insertBeforeImpl(ilist_node_base &Next, ilist_node_base &N) {<br>
+    ilist_node_base &Prev = *Next.getPrev();<br>
+    N.setNext(&Next);<br>
+    N.setPrev(&Prev);<br>
+    Prev.setNext(&N);<br>
+    Next.setPrev(&N);<br>
+  }<br>
+<br>
+  static void removeImpl(ilist_node_base &N) {<br>
+    ilist_node_base *Prev = N.getPrev();<br>
+    ilist_node_base *Next = N.getNext();<br>
+    Next->setPrev(Prev);<br>
+    Prev->setNext(Next);<br>
+<br>
+    // Not strictly necessary, but helps catch a class of bugs.<br>
+    N.setPrev(nullptr);<br>
+    N.setNext(nullptr);<br>
+  }<br>
+<br>
+  static void transferBeforeImpl(ilist_node_base &Next, ilist_node_base &First,<br>
+                                 ilist_node_base &Last) {<br>
+    assert(&Next != &Last && "Should be checked by callers");<br>
+    assert(&First != &Last && "Should be checked by callers");<br>
+    // Position cannot be contained in the range to be transferred.<br>
+    assert(&Next != &First &&<br>
+           // Check for the most common mistake.<br>
+           "Insertion point can't be one of the transferred nodes");<br>
+<br>
+    ilist_node_base &Final = *Last.getPrev();<br>
+<br>
+    // Detach from old list/position.<br>
+    First.getPrev()->setNext(&Last);<br>
+    Last.setPrev(First.getPrev());<br>
+<br>
+    // Splice [First, Final] into its new list/position.<br>
+    ilist_node_base &Prev = *Next.getPrev();<br>
+    Final.setNext(&Next);<br>
+    First.setPrev(&Prev);<br>
+    Prev.setNext(&First);<br>
+    Next.setPrev(&Final);<br>
+  }<br>
+<br>
+  template <class T><br>
+  static void insertBefore(ilist_node<T> &Next, ilist_node<T> &N) {<br>
+    insertBeforeImpl(Next, N);<br>
+  }<br>
+<br>
+  template <class T> static void remove(ilist_node<T> &N) { removeImpl(N); }<br>
+<br>
+  template <class T><br>
+  static void transferBefore(ilist_node<T> &Next, ilist_node<T> &First,<br>
+                             ilist_node<T> &Last) {<br>
+    transferBeforeImpl(Next, First, Last);<br>
+  }<br>
+};<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 //<br>
@@ -280,7 +327,7 @@ template<typename NodeTy> struct simplif<br>
 /// ilist_sentinel, which holds pointers to the first and last nodes in the<br>
 /// list.<br>
 template <typename NodeTy, typename Traits = ilist_traits<NodeTy>><br>
-class iplist : public Traits, ilist_node_access {<br>
+class iplist : public Traits, ilist_base, ilist_node_access {<br>
   // TODO: Drop this assertion and the transitive type traits anytime after<br>
   // v4.0 is branched (i.e,. keep them for one release to help out-of-tree code<br>
   // update).<br>
@@ -356,13 +403,7 @@ public:<br>
   }<br>
<br>
   iterator insert(iterator where, NodeTy *New) {<br>
-    node_type *NewN = this->getNodePtr(New);<br>
-    node_type *Next = where.getNodePtr();<br>
-    node_type *Prev = this->getPrev(Next);<br>
-    this->setNext(NewN, Next);<br>
-    this->setPrev(NewN, Prev);<br>
-    this->setNext(Prev, NewN);<br>
-    this->setPrev(Next, NewN);<br>
+    ilist_base::insertBefore(*where.getNodePtr(), *this->getNodePtr(New));<br>
<br>
     this->addNodeToList(New);  // Notify traits that we added a node...<br>
     return iterator(New);<br>
@@ -381,24 +422,9 @@ public:<br>
<br>
   NodeTy *remove(iterator &IT) {<br>
     assert(IT != end() && "Cannot remove end of list!");<br>
-    NodeTy *Node = &*IT;<br>
-    node_type *Base = this->getNodePtr(Node);<br>
-    node_type *Next = this->getNext(Base);<br>
-    node_type *Prev = this->getPrev(Base);<br>
-<br>
-    this->setNext(Prev, Next);<br>
-    this->setPrev(Next, Prev);<br>
-    IT = iterator(*Next);<br>
+    NodeTy *Node = &*IT++;<br>
+    ilist_base::remove(*this->getNodePtr(Node));<br>
     this->removeNodeFromList(Node);  // Notify traits that we removed a node...<br>
-<br>
-    // Set the next/prev pointers of the current node to null.  This isn't<br>
-    // strictly required, but this catches errors where a node is removed from<br>
-    // an ilist (and potentially deleted) with iterators still pointing at it.<br>
-    // After those iterators are incremented or decremented, they become<br>
-    // default-constructed iterators, and will assert on increment, decrement,<br>
-    // and dereference instead of "usually working".<br>
-    this->setNext(Base, nullptr);<br>
-    this->setPrev(Base, nullptr);<br>
     return Node;<br>
   }<br>
<br>
@@ -431,32 +457,11 @@ private:<br>
   // [first, last) into position.<br>
   //<br>
   void transfer(iterator position, iplist &L2, iterator first, iterator last) {<br>
-    assert(first != last && "Should be checked by callers");<br>
-    // Position cannot be contained in the range to be transferred.<br>
-    assert(position != first &&<br>
-           // Check for the most common mistake.<br>
-           "Insertion point can't be one of the transferred nodes");<br>
-<br>
     if (position == last)<br>
       return;<br>
<br>
-    // Get raw hooks to the first and final nodes being transferred.<br>
-    node_type *First = first.getNodePtr();<br>
-    node_type *Final = (--last).getNodePtr();<br>
-<br>
-    // Detach from old list/position.<br>
-    node_type *Prev = this->getPrev(First);<br>
-    node_type *Next = this->getNext(Final);<br>
-    this->setNext(Prev, Next);<br>
-    this->setPrev(Next, Prev);<br>
-<br>
-    // Splice [First, Final] into its new list/position.<br>
-    Next = position.getNodePtr();<br>
-    Prev = this->getPrev(Next);<br>
-    this->setNext(Final, Next);<br>
-    this->setPrev(First, Prev);<br>
-    this->setNext(Prev, First);<br>
-    this->setPrev(Next, Final);<br>
+    ilist_base::transferBefore(*position.getNodePtr(), *first.getNodePtr(),<br>
+                               *last.getNodePtr());<br>
<br>
     // Callback.  Note that the nodes have moved from before-last to<br>
     // before-position.<br>
<br>
Modified: llvm/trunk/include/llvm/ADT/ilist_node.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist_node.h?rev=279484&r1=279483&r2=279484&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist_node.h?rev=279484&r1=279483&r2=279484&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ADT/ilist_node.h (original)<br>
+++ llvm/trunk/include/llvm/ADT/ilist_node.h Mon Aug 22 17:21:07 2016<br>
@@ -23,18 +23,22 @@ template<typename NodeTy><br>
 struct ilist_traits;<br>
<br>
 /// Base class for ilist nodes.<br>
-struct ilist_node_base {<br>
+class ilist_node_base {<br>
 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS<br>
   PointerIntPair<ilist_node_base *, 1> PrevAndSentinel;<br>
+#else<br>
+  ilist_node_base *Prev = nullptr;<br>
+#endif<br>
+  ilist_node_base *Next = nullptr;<br>
<br>
+public:<br>
+#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS<br>
   void setPrev(ilist_node_base *Prev) { PrevAndSentinel.setPointer(Prev); }<br>
   ilist_node_base *getPrev() const { return PrevAndSentinel.getPointer(); }<br>
<br>
   bool isKnownSentinel() const { return PrevAndSentinel.getInt(); }<br>
   void initializeSentinel() { PrevAndSentinel.setInt(true); }<br>
 #else<br>
-  ilist_node_base *Prev = nullptr;<br>
-<br>
   void setPrev(ilist_node_base *Prev) { this->Prev = Prev; }<br>
   ilist_node_base *getPrev() const { return Prev; }<br>
<br>
@@ -42,7 +46,8 @@ struct ilist_node_base {<br>
   void initializeSentinel() {}<br>
 #endif<br>
<br>
-  ilist_node_base *Next = nullptr;<br>
+  void setNext(ilist_node_base *Next) { this->Next = Next; }<br>
+  ilist_node_base *getNext() const { return Next; }<br>
 };<br>
<br>
 struct ilist_node_access;<br>
@@ -51,6 +56,7 @@ template <typename NodeTy> class ilist_s<br>
<br>
 /// Templated wrapper class.<br>
 template <typename NodeTy> class ilist_node : ilist_node_base {<br>
+  friend class ilist_base;<br>
   friend struct ilist_node_access;<br>
   friend struct ilist_traits<NodeTy>;<br>
   friend class ilist_iterator<NodeTy>;<br>
@@ -63,15 +69,19 @@ private:<br>
   ilist_node *getPrev() {<br>
     return static_cast<ilist_node *>(ilist_node_base::getPrev());<br>
   }<br>
-  ilist_node *getNext() { return static_cast<ilist_node *>(Next); }<br>
+  ilist_node *getNext() {<br>
+    return static_cast<ilist_node *>(ilist_node_base::getNext());<br>
+  }<br>
<br>
   const ilist_node *getPrev() const {<br>
     return static_cast<ilist_node *>(ilist_node_base::getPrev());<br>
   }<br>
-  const ilist_node *getNext() const { return static_cast<ilist_node *>(Next); }<br>
+  const ilist_node *getNext() const {<br>
+    return static_cast<ilist_node *>(ilist_node_base::getNext());<br>
+  }<br>
<br>
   void setPrev(ilist_node *N) { ilist_node_base::setPrev(N); }<br>
-  void setNext(ilist_node *N) { Next = N; }<br>
+  void setNext(ilist_node *N) { ilist_node_base::setNext(N); }<br>
<br>
 public:<br>
   ilist_iterator<NodeTy> getIterator() { return ilist_iterator<NodeTy>(*this); }<br>
<br>
Modified: llvm/trunk/unittests/ADT/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/CMakeLists.txt?rev=279484&r1=279483&r2=279484&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/CMakeLists.txt?rev=279484&r1=279483&r2=279484&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ADT/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/ADT/CMakeLists.txt Mon Aug 22 17:21:07 2016<br>
@@ -18,6 +18,9 @@ set(ADTSources<br>
   FunctionRefTest.cpp<br>
   HashingTest.cpp<br>
   ilistTest.cpp<br>
+  IListBaseTest.cpp<br>
+  IListNodeBaseTest.cpp<br>
+  IListSentinelTest.cpp<br>
   ImmutableMapTest.cpp<br>
   ImmutableSetTest.cpp<br>
   IntEqClassesTest.cpp<br>
<br>
Added: llvm/trunk/unittests/ADT/IListBaseTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListBaseTest.cpp?rev=279484&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListBaseTest.cpp?rev=279484&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ADT/IListBaseTest.cpp (added)<br>
+++ llvm/trunk/unittests/ADT/IListBaseTest.cpp Mon Aug 22 17:21:07 2016<br>
@@ -0,0 +1,102 @@<br>
+//===- unittests/ADT/IListBaseTest.cpp - ilist_base unit tests ------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/ilist.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+<br>
+TEST(IListBaseTest, insertBeforeImpl) {<br>
+  ilist_node_base S, A, B;<br>
+  // [S] <-> [S]<br>
+  S.setPrev(&S);<br>
+  S.setNext(&S);<br>
+<br>
+  // [S] <-> A <-> [S]<br>
+  ilist_base::insertBeforeImpl(S, A);<br>
+  EXPECT_EQ(&A, S.getPrev());<br>
+  EXPECT_EQ(&S, A.getPrev());<br>
+  EXPECT_EQ(&A, S.getNext());<br>
+  EXPECT_EQ(&S, A.getNext());<br>
+<br>
+  // [S] <-> A <-> B <-> [S]<br>
+  ilist_base::insertBeforeImpl(S, B);<br>
+  EXPECT_EQ(&B, S.getPrev());<br>
+  EXPECT_EQ(&A, B.getPrev());<br>
+  EXPECT_EQ(&S, A.getPrev());<br>
+  EXPECT_EQ(&A, S.getNext());<br>
+  EXPECT_EQ(&B, A.getNext());<br>
+  EXPECT_EQ(&S, B.getNext());<br>
+}<br>
+<br>
+TEST(IListBaseTest, removeImpl) {<br>
+  ilist_node_base S, A, B;<br>
+<br>
+  // [S] <-> A <-> B <-> [S]<br>
+  S.setPrev(&S);<br>
+  S.setNext(&S);<br>
+  ilist_base::insertBeforeImpl(S, A);<br>
+  ilist_base::insertBeforeImpl(S, B);<br>
+<br>
+  // [S] <-> B <-> [S]<br>
+  ilist_base::removeImpl(A);<br>
+  EXPECT_EQ(&B, S.getPrev());<br>
+  EXPECT_EQ(&S, B.getPrev());<br>
+  EXPECT_EQ(&B, S.getNext());<br>
+  EXPECT_EQ(&S, B.getNext());<br>
+  EXPECT_EQ(nullptr, A.getPrev());<br>
+  EXPECT_EQ(nullptr, A.getNext());<br>
+<br>
+  // [S] <-> [S]<br>
+  ilist_base::removeImpl(B);<br>
+  EXPECT_EQ(&S, S.getPrev());<br>
+  EXPECT_EQ(&S, S.getNext());<br>
+  EXPECT_EQ(nullptr, B.getPrev());<br>
+  EXPECT_EQ(nullptr, B.getNext());<br>
+}<br>
+<br>
+TEST(IListBaseTest, transferBeforeImpl) {<br>
+  ilist_node_base S1, S2, A, B, C, D, E;<br>
+<br>
+  // [S1] <-> A <-> B <-> C <-> [S1]<br>
+  S1.setPrev(&S1);<br>
+  S1.setNext(&S1);<br>
+  ilist_base::insertBeforeImpl(S1, A);<br>
+  ilist_base::insertBeforeImpl(S1, B);<br>
+  ilist_base::insertBeforeImpl(S1, C);<br>
+<br>
+  // [S2] <-> D <-> E <-> [S2]<br>
+  S2.setPrev(&S2);<br>
+  S2.setNext(&S2);<br>
+  ilist_base::insertBeforeImpl(S2, D);<br>
+  ilist_base::insertBeforeImpl(S2, E);<br>
+<br>
+  // [S1] <-> C <-> [S1]<br>
+  ilist_base::transferBeforeImpl(D, A, C);<br>
+  EXPECT_EQ(&C, S1.getPrev());<br>
+  EXPECT_EQ(&S1, C.getPrev());<br>
+  EXPECT_EQ(&C, S1.getNext());<br>
+  EXPECT_EQ(&S1, C.getNext());<br>
+<br>
+  // [S2] <-> A <-> B <-> D <-> E <-> [S2]<br>
+  EXPECT_EQ(&E, S2.getPrev());<br>
+  EXPECT_EQ(&D, E.getPrev());<br>
+  EXPECT_EQ(&B, D.getPrev());<br>
+  EXPECT_EQ(&A, B.getPrev());<br>
+  EXPECT_EQ(&S2, A.getPrev());<br>
+  EXPECT_EQ(&A, S2.getNext());<br>
+  EXPECT_EQ(&B, A.getNext());<br>
+  EXPECT_EQ(&D, B.getNext());<br>
+  EXPECT_EQ(&E, D.getNext());<br>
+  EXPECT_EQ(&S2, E.getNext());<br>
+}<br>
+<br>
+} // end namespace<br>
<br>
Added: llvm/trunk/unittests/ADT/IListNodeBaseTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListNodeBaseTest.cpp?rev=279484&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListNodeBaseTest.cpp?rev=279484&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ADT/IListNodeBaseTest.cpp (added)<br>
+++ llvm/trunk/unittests/ADT/IListNodeBaseTest.cpp Mon Aug 22 17:21:07 2016<br>
@@ -0,0 +1,60 @@<br>
+//===- unittests/ADT/IListNodeBaseTest.cpp - ilist_node_base unit tests ---===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/ilist_node.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+<br>
+TEST(IListNodeBaseTest, DefaultConstructor) {<br>
+  ilist_node_base A;<br>
+  EXPECT_EQ(nullptr, A.getPrev());<br>
+  EXPECT_EQ(nullptr, A.getNext());<br>
+  EXPECT_FALSE(A.isKnownSentinel());<br>
+}<br>
+<br>
+TEST(IListNodeBaseTest, setPrevAndNext) {<br>
+  ilist_node_base A, B, C;<br>
+  A.setPrev(&B);<br>
+  EXPECT_EQ(&B, A.getPrev());<br>
+  EXPECT_EQ(nullptr, A.getNext());<br>
+  EXPECT_EQ(nullptr, B.getPrev());<br>
+  EXPECT_EQ(nullptr, B.getNext());<br>
+  EXPECT_EQ(nullptr, C.getPrev());<br>
+  EXPECT_EQ(nullptr, C.getNext());<br>
+<br>
+  A.setNext(&C);<br>
+  EXPECT_EQ(&B, A.getPrev());<br>
+  EXPECT_EQ(&C, A.getNext());<br>
+  EXPECT_EQ(nullptr, B.getPrev());<br>
+  EXPECT_EQ(nullptr, B.getNext());<br>
+  EXPECT_EQ(nullptr, C.getPrev());<br>
+  EXPECT_EQ(nullptr, C.getNext());<br>
+}<br>
+<br>
+TEST(IListNodeBaseTest, isKnownSentinel) {<br>
+  ilist_node_base A, B;<br>
+  EXPECT_FALSE(A.isKnownSentinel());<br>
+  A.setPrev(&B);<br>
+  A.setNext(&B);<br>
+  EXPECT_EQ(&B, A.getPrev());<br>
+  EXPECT_EQ(&B, A.getNext());<br>
+  A.initializeSentinel();<br>
+#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS<br>
+  EXPECT_TRUE(A.isKnownSentinel());<br>
+#else<br>
+  EXPECT_FALSE(A.isKnownSentinel());<br>
+#endif<br>
+  EXPECT_EQ(&B, A.getPrev());<br>
+  EXPECT_EQ(&B, A.getNext());<br>
+}<br>
+<br>
+} // end namespace<br>
<br>
Added: llvm/trunk/unittests/ADT/IListSentinelTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListSentinelTest.cpp?rev=279484&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListSentinelTest.cpp?rev=279484&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ADT/IListSentinelTest.cpp (added)<br>
+++ llvm/trunk/unittests/ADT/IListSentinelTest.cpp Mon Aug 22 17:21:07 2016<br>
@@ -0,0 +1,37 @@<br>
+//===- unittests/ADT/IListSentinelTest.cpp - ilist_sentinel unit tests ----===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/ilist.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+<br>
+class Node : public ilist_node<Node> {};<br>
+<br>
+TEST(IListSentinelTest, DefaultConstructor) {<br>
+  ilist_sentinel<Node> S;<br>
+  EXPECT_EQ(&S, ilist_node_access::getPrev(S));<br>
+  EXPECT_EQ(&S, ilist_node_access::getNext(S));<br>
+#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS<br>
+  EXPECT_TRUE(S.isKnownSentinel());<br>
+#else<br>
+  EXPECT_FALSE(S.isKnownSentinel());<br>
+#endif<br>
+}<br>
+<br>
+TEST(IListSentinelTest, NormalNodeIsNotKnownSentinel) {<br>
+  Node N;<br>
+  EXPECT_EQ(nullptr, ilist_node_access::getPrev(N));<br>
+  EXPECT_EQ(nullptr, ilist_node_access::getNext(N));<br>
+  EXPECT_FALSE(N.isKnownSentinel());<br>
+}<br>
+<br>
+} // end namespace<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>