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

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 5 07:02:02 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/74482.diff


3 Files Affected:

- (modified) libcxx/include/__config (+6) 
- (modified) libcxx/include/array (+8-2) 
- (modified) libcxx/include/string_view (+5-2) 


``````````diff
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 3de4d610e8cde..636f46b048554 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -168,6 +168,12 @@
 // pointer from 16 to 8. This changes the output of std::string::max_size,
 // which makes it ABI breaking
 #    define _LIBCPP_ABI_STRING_8_BYTE_ALIGNMENT
+// Define std::array iterators to be __wrap_iters instead of raw pointers, which
+// prevents people from relying on a non-portable implementation detail.
+#    define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
+// Define std::basic_string_view iterators to be __wrap_iters instead of raw pointers,
+// which prevents people from relying on a non-portable implementation detail.
+#    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/array b/libcxx/include/array
index fc5371ebae21a..988464844f866 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>
@@ -168,10 +169,15 @@ struct _LIBCPP_TEMPLATE_VIS array
     typedef _Tp                                   value_type;
     typedef value_type&                           reference;
     typedef const value_type&                     const_reference;
-    typedef value_type*                           iterator;
-    typedef const value_type*                     const_iterator;
     typedef value_type*                           pointer;
     typedef const value_type*                     const_pointer;
+#if defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY)
+    typedef __wrap_iter<pointer>                  iterator;
+    typedef __wrap_iter<const_pointer>            const_iterator;
+#else
+    typedef pointer                               iterator;
+    typedef const_pointer                         const_iterator;
+#endif
     typedef size_t                                size_type;
     typedef ptrdiff_t                             difference_type;
     typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 881e321c507f6..8af67d5e5bb11 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>
@@ -279,10 +280,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 = _VSTD::reverse_iterator<const_iterator>;

``````````

</details>


https://github.com/llvm/llvm-project/pull/74482


More information about the libcxx-commits mailing list