[libcxx-commits] [libcxx] [libc++] Always initialize __tree::{, const_}iterator (PR #147167)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 13 00:15:24 PDT 2025


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/147167

>From df4c5a880fe18f9a0abb136d2bb407e20ba411fc Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 6 Jul 2025 01:26:04 +0200
Subject: [PATCH] [libc++] Always initialize __tree::{,const_}iterator

---
 libcxx/include/__tree                         | 14 +----
 .../always_initialize_iterators.pass.cpp      | 53 +++++++++++++++++++
 2 files changed, 55 insertions(+), 12 deletions(-)
 create mode 100644 libcxx/test/extensions/libcxx/always_initialize_iterators.pass.cpp

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index b3c0ece8e5fdb..f29b691b73dda 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -646,12 +646,7 @@ public:
   using reference         = value_type&;
   using pointer           = __rebind_pointer_t<_NodePtr, value_type>;
 
-  _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER >= 14
-      : __ptr_(nullptr)
-#endif
-  {
-  }
+  _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
 
   _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
   _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
@@ -720,12 +715,7 @@ public:
   using reference         = const value_type&;
   using pointer           = __rebind_pointer_t<_NodePtr, const value_type>;
 
-  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT
-#if _LIBCPP_STD_VER >= 14
-      : __ptr_(nullptr)
-#endif
-  {
-  }
+  _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
 
 private:
   typedef __tree_iterator<_Tp, __node_pointer, difference_type> __non_const_iterator;
diff --git a/libcxx/test/extensions/libcxx/always_initialize_iterators.pass.cpp b/libcxx/test/extensions/libcxx/always_initialize_iterators.pass.cpp
new file mode 100644
index 0000000000000..1893ca913ad01
--- /dev/null
+++ b/libcxx/test/extensions/libcxx/always_initialize_iterators.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// Make sure that that the iterator types of the associative containers is initialized even when default initialized.
+// This is an extension because the standard only requires initialization when an iterator is value initialized, and
+// that only since C++14. We guarantee that iterators are always initialized, even in C++11.
+
+#include <cassert>
+#include <map>
+#include <set>
+
+template <class Iter>
+void test() {
+  {
+    Iter iter1;
+    Iter iter2;
+    assert(iter1 == iter2);
+  }
+  {
+    Iter iter1;
+    Iter iter2{};
+    assert(iter1 == iter2);
+  }
+  {
+    Iter iter1{};
+    Iter iter2;
+    assert(iter1 == iter2);
+  }
+}
+
+template <class Container>
+void test_container() {
+  test<typename Container::iterator>();
+  test<typename Container::const_iterator>();
+  test<typename Container::reverse_iterator>();
+  test<typename Container::const_reverse_iterator>();
+}
+
+int main(int, char**) {
+  test_container<std::map<int, int>>();
+  test_container<std::multimap<int, int>>();
+  test_container<std::set<int>>();
+  test_container<std::multiset<int>>();
+
+  return 0;
+}



More information about the libcxx-commits mailing list