Implement NULL iterators for <list> re: N3644

llvm-svn: 187740
diff --git a/libcxx/include/list b/libcxx/include/list
index 4041b88..4b1272a 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -273,7 +273,7 @@
     typedef typename pointer_traits<pointer>::difference_type difference_type;
 
     _LIBCPP_INLINE_VISIBILITY
-    __list_iterator() _NOEXCEPT
+    __list_iterator() _NOEXCEPT : __ptr_(nullptr)
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __get_db()->__insert_i(this);
@@ -403,7 +403,7 @@
     typedef typename pointer_traits<pointer>::difference_type difference_type;
 
     _LIBCPP_INLINE_VISIBILITY
-    __list_const_iterator() _NOEXCEPT
+    __list_const_iterator() _NOEXCEPT : __ptr_(nullptr)
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __get_db()->__insert_i(this);
diff --git a/libcxx/test/containers/sequences/list/db_iterators_9.pass.cpp b/libcxx/test/containers/sequences/list/db_iterators_9.pass.cpp
new file mode 100644
index 0000000..6f4a5af
--- /dev/null
+++ b/libcxx/test/containers/sequences/list/db_iterators_9.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// Operations on "NULL" iterators
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) do { if (!x) throw 1; } while(0)
+
+#include <list>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+struct S { int val; };
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+    {
+	unsigned lib_asserts;
+
+    typedef S T;
+    typedef std::list<T> C;
+    C::iterator i{};
+    C::const_iterator ci{};
+    
+    lib_asserts = 0;
+    try { ++i; }  catch (int) { ++lib_asserts; }
+    try { i++; }  catch (int) { ++lib_asserts; }
+    try { ++ci; } catch (int) { ++lib_asserts; }
+    try { ci++; } catch (int) { ++lib_asserts; }
+    assert(lib_asserts == 4);
+
+    lib_asserts = 0;
+    try { --i; }  catch (int) { ++lib_asserts; }
+    try { i--; }  catch (int) { ++lib_asserts; }
+    try { --ci; } catch (int) { ++lib_asserts; }
+    try { ci--; } catch (int) { ++lib_asserts; }
+    assert(lib_asserts == 4);
+
+    lib_asserts = 0;
+    try { *i; }             catch (int) { ++lib_asserts; }
+    try { *ci; }            catch (int) { ++lib_asserts; }
+    try { (void)  i->val; } catch (int) { ++lib_asserts; }
+    try { (void) ci->val; } catch (int) { ++lib_asserts; }
+    assert(lib_asserts == 4);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/libcxx/test/containers/sequences/list/iterators.pass.cpp b/libcxx/test/containers/sequences/list/iterators.pass.cpp
index 94e4200..9f6a51b 100644
--- a/libcxx/test/containers/sequences/list/iterators.pass.cpp
+++ b/libcxx/test/containers/sequences/list/iterators.pass.cpp
@@ -135,4 +135,22 @@
         assert(j->first == 3);
     }
 #endif
+#if _LIBCPP_STD_VER > 11
+    {
+        std::list<int> c;
+        std::list<int>::iterator ii1{}, ii2{};
+        std::list<int>::iterator ii4 = ii1;
+        std::list<int>::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+
+        assert ( ii1 != c.cbegin());
+        assert ( cii != c.begin());
+    }
+#endif
+
 }