diff options
author | Louis Dionne <ldionne.2@gmail.com> | 2024-03-04 18:23:53 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-04 18:23:53 -0500 |
commit | 5174b3802575425dcbc58680ccce10961fdb8b67 (patch) | |
tree | 0cf98cdf97ad4583d2e4cb096f7a8cfe546fe0df /libcxx | |
parent | 4d80df0922ef7e48d53d4ae382977d8a2ff34ce0 (diff) | |
download | llvm-5174b3802575425dcbc58680ccce10961fdb8b67.zip llvm-5174b3802575425dcbc58680ccce10961fdb8b67.tar.gz llvm-5174b3802575425dcbc58680ccce10961fdb8b67.tar.bz2 |
[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.
Diffstat (limited to 'libcxx')
-rw-r--r-- | libcxx/include/__config | 6 | ||||
-rw-r--r-- | libcxx/include/__iterator/wrap_iter.h | 4 | ||||
-rw-r--r-- | libcxx/include/array | 22 | ||||
-rw-r--r-- | libcxx/include/string_view | 11 |
4 files changed, 31 insertions, 12 deletions
diff --git a/libcxx/include/__config b/libcxx/include/__config index 8d4d173..3a438e8 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 3827241..3124826 100644 --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -97,10 +97,14 @@ private: 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 961b620..7fa5dc1 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 difference_type = ptrdiff_t; using reverse_iterator = std::reverse_iterator<iterator>; diff --git a/libcxx/include/string_view b/libcxx/include/string_view index 48bbcd8..e0dd5c5 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 } |