[libcxx-commits] [libcxx] 5174b38 - [libc++] Use __wrap_iter in string_view and array in the unstable ABI (#74482)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Mar 4 15:23:57 PST 2024


Author: Louis Dionne
Date: 2024-03-04T18:23:53-05:00
New Revision: 5174b3802575425dcbc58680ccce10961fdb8b67

URL: https://github.com/llvm/llvm-project/commit/5174b3802575425dcbc58680ccce10961fdb8b67
DIFF: https://github.com/llvm/llvm-project/commit/5174b3802575425dcbc58680ccce10961fdb8b67.diff

LOG: [libc++] Use __wrap_iter in string_view and array in the unstable ABI (#74482)

std::string_view and std::array iterators don't have to be raw pointers,
and in fact other implementations don't represent them as raw pointers.
Them being raw pointers in libc++ makes it easier for users to write
non-portable code. This is bad in itself, but this is even worse when
considering efforts like hardening where we want an easy ability to
swap for a different iterator type. If users depend on iterators being
raw pointers, this becomes a build break.

Hence, this patch enables the use of __wrap_iter in the unstable ABI,
creating a long term path towards making this the default. This patch
may break code that assumes these iterators are raw pointers for
people compiling with the unstable ABI.

This patch also removes several assumptions that array iterators are
raw pointers in the code base and in the test suite.

Added: 
    

Modified: 
    libcxx/include/__config
    libcxx/include/__iterator/wrap_iter.h
    libcxx/include/array
    libcxx/include/string_view

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__config b/libcxx/include/__config
index 8d4d17378b2973..3a438e85a7b819 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -174,6 +174,12 @@
 // The implementation moved to the header, but we still export the symbols from
 // the dylib for backwards compatibility.
 #    define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
+// Define std::array/std::string_view iterators to be __wrap_iters instead of raw
+// pointers, which prevents people from relying on a non-portable implementation
+// detail. This is especially useful because enabling bounded iterators hardening
+// requires code not to make these assumptions.
+#    define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
+#    define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
 #  elif _LIBCPP_ABI_VERSION == 1
 #    if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
 // Enable compiling copies of now inline methods into the dylib to support

diff  --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h
index 3827241e5fe476..3124826189ad7c 100644
--- a/libcxx/include/__iterator/wrap_iter.h
+++ b/libcxx/include/__iterator/wrap_iter.h
@@ -97,10 +97,14 @@ class __wrap_iter {
   friend class __wrap_iter;
   template <class _CharT, class _Traits, class _Alloc>
   friend class basic_string;
+  template <class _CharT, class _Traits>
+  friend class basic_string_view;
   template <class _Tp, class _Alloc>
   friend class _LIBCPP_TEMPLATE_VIS vector;
   template <class _Tp, size_t>
   friend class _LIBCPP_TEMPLATE_VIS span;
+  template <class _Tp, size_t _Size>
+  friend struct array;
 };
 
 template <class _Iter1>

diff  --git a/libcxx/include/array b/libcxx/include/array
index 961b620efb9357..7fa5dc1479349e 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -120,6 +120,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
 #include <__config>
 #include <__fwd/array.h>
 #include <__iterator/reverse_iterator.h>
+#include <__iterator/wrap_iter.h>
 #include <__tuple/sfinae_helpers.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/is_array.h>
@@ -167,14 +168,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp, size_t _Size>
 struct _LIBCPP_TEMPLATE_VIS array {
   // types:
-  using __self                 = array;
-  using value_type             = _Tp;
-  using reference              = value_type&;
-  using const_reference        = const value_type&;
-  using iterator               = value_type*;
-  using const_iterator         = const value_type*;
-  using pointer                = value_type*;
-  using const_pointer          = const value_type*;
+  using __self          = array;
+  using value_type      = _Tp;
+  using reference       = value_type&;
+  using const_reference = const value_type&;
+  using pointer         = value_type*;
+  using const_pointer   = const value_type*;
+#if defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY)
+  using iterator       = __wrap_iter<pointer>;
+  using const_iterator = __wrap_iter<const_pointer>;
+#else
+  using iterator       = pointer;
+  using const_iterator = const_pointer;
+#endif
   using size_type              = size_t;
   using 
diff erence_type        = ptr
diff _t;
   using reverse_iterator       = std::reverse_iterator<iterator>;

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index 48bbcd80021670..e0dd5c5b19ace0 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -215,6 +215,7 @@ namespace std {
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
+#include <__iterator/wrap_iter.h>
 #include <__memory/pointer_traits.h>
 #include <__ranges/concepts.h>
 #include <__ranges/data.h>
@@ -278,10 +279,12 @@ public:
   using const_pointer   = const _CharT*;
   using reference       = _CharT&;
   using const_reference = const _CharT&;
-#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
+#if defined(_LIBCPP_ABI_BOUNDED_ITERATORS)
   using const_iterator = __bounded_iter<const_pointer>;
+#elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW)
+  using const_iterator = __wrap_iter<const_pointer>;
 #else
-  using const_iterator = const_pointer; // See [string.view.iterators]
+  using const_iterator = const_pointer;
 #endif
   using iterator                                = const_iterator;
   using const_reverse_iterator                  = std::reverse_iterator<const_iterator>;
@@ -353,7 +356,7 @@ public:
 #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
     return std::__make_bounded_iter(data(), data(), data() + size());
 #else
-    return __data_;
+    return const_iterator(__data_);
 #endif
   }
 
@@ -361,7 +364,7 @@ public:
 #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
     return std::__make_bounded_iter(data() + size(), data(), data() + size());
 #else
-    return __data_ + __size_;
+    return const_iterator(__data_ + __size_);
 #endif
   }
 


        


More information about the libcxx-commits mailing list