diff --git a/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake b/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake index 699d3f8866861..66b964bf27b3f 100644 --- a/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake +++ b/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake @@ -1,7 +1,8 @@ set(LIBCXX_HARDENING_MODE "fast" CACHE STRING "") set(_defines - _LIBCPP_ABI_BOUNDED_ITERATORS + _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING + _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW _LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR _LIBCPP_ABI_BOUNDED_UNIQUE_PTR _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY diff --git a/libcxx/docs/ABIGuarantees.rst b/libcxx/docs/ABIGuarantees.rst index c7d5afe1080bb..fc08e17607945 100644 --- a/libcxx/docs/ABIGuarantees.rst +++ b/libcxx/docs/ABIGuarantees.rst @@ -178,8 +178,8 @@ This changes the ``iterator`` and ``const_iterator`` of ``array`` and ``string_v ``__wrap_iter`` instead, which makes it less likely for users to depend on non-portable implementation details. This is especially useful because enabling bounded iterators hardening requires code not to make these assumptions. -``_LIBCPP_ABI_BOUNDED_ITERATORS``, ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING``, ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR``, and ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY`` -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_{STRING,STRING_VIEW,SPAN,VECTOR,STD_ARRAY}`` +------------------------------------------------------------------------------- These flags change the ``iterator`` member of various classes to reference hardened iterators instead. See the :ref:`hardening documentation ` for more details. diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst index 17808841bd9ec..6d4e0883f6b1a 100644 --- a/libcxx/docs/Hardening.rst +++ b/libcxx/docs/Hardening.rst @@ -314,22 +314,28 @@ itself) to enable additional hardening checks. This is done by passing these macros as ``-DLIBCXX_ABI_DEFINES="_LIBCPP_ABI_FOO;_LIBCPP_ABI_BAR;etc"`` at CMake configuration time. The available options are: -- ``_LIBCPP_ABI_BOUNDED_ITERATORS`` -- changes the iterator type of select - containers (see below) to a bounded iterator that keeps track of whether it's - within the bounds of the original container and asserts valid bounds on every - dereference. +- ``_LIBCPP_ABI_BOUNDED_ITERATORS`` -- historical equivalent to defining both + ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW`` and ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN``. - ABI impact: changes the iterator type of the relevant containers. +- ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW`` -- changes the iterator type of + ``basic_string_view`` to a bounded iterator that keeps track of whether it's within + the bounds of the original container and asserts it on every dereference and + when performing iterator arithmetic. + + ABI impact: changes the iterator type of ``basic_string_view`` and its + specializations, such as ``string_view`` and ``wstring_view``. - Supported containers: +- ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN`` -- changes the iterator type of ``span`` + to a bounded iterator that keeps track of whether it's within the bounds of the + original container and asserts it on every dereference and when performing iterator + arithmetic. - - ``span``; - - ``string_view``. + ABI impact: changes the iterator type of ``span``. - ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING`` -- changes the iterator type of ``basic_string`` to a bounded iterator that keeps track of whether it's within the bounds of the original container and asserts it on every dereference and - when performing iterator arithmetics. + when performing iterator arithmetic. ABI impact: changes the iterator type of ``basic_string`` and its specializations, such as ``string`` and ``wstring``. @@ -337,7 +343,7 @@ CMake configuration time. The available options are: - ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR`` -- changes the iterator type of ``vector`` to a bounded iterator that keeps track of whether it's within the bounds of the original container and asserts it on every dereference and when - performing iterator arithmetics. Note: this doesn't yet affect + performing iterator arithmetic. Note: this doesn't yet affect ``vector``. ABI impact: changes the iterator type of ``vector`` (except ``vector``). diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst index 8661e5898fbc0..2018f19231978 100644 --- a/libcxx/docs/ReleaseNotes/21.rst +++ b/libcxx/docs/ReleaseNotes/21.rst @@ -77,6 +77,10 @@ Improvements and New Features - The ``bitset::to_string`` function has been optimized, resulting in a performance improvement of up to 8.3x for bitsets with uniformly distributed zeros and ones, and up to 13.5x and 16.1x for sparse and dense bitsets, respectively. +- The ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW`` and ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN`` macros were added. + These macros control bounded iterators in ``string_view`` and ``span`` respectively. This was previously controled by + the single macro ``_LIBCPP_ABI_BOUNDED_ITERATORS``. + Deprecations and Removals ------------------------- diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h index a75cd0a675339..b2b22ccbff101 100644 --- a/libcxx/include/__configuration/abi.h +++ b/libcxx/include/__configuration/abi.h @@ -113,6 +113,15 @@ # define _LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING #endif +#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifndef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW +# define _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW +# endif +# ifndef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN +# define _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN +# endif +#endif + // Tracks the bounds of the array owned by std::unique_ptr, allowing it to trap when accessed out-of-bounds. // Note that limited bounds checking is also available outside of this ABI configuration, but only some categories // of types can be checked. diff --git a/libcxx/include/span b/libcxx/include/span index 3d4f9e4ba7831..90afa278d0a70 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -240,7 +240,7 @@ public: using const_pointer = const _Tp*; using reference = _Tp&; using const_reference = const _Tp&; -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN using iterator = __bounded_iter; # else using iterator = __wrap_iter; @@ -383,14 +383,14 @@ public: // [span.iter], span iterator support _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN return std::__make_bounded_iter(data(), data(), data() + size()); # else return iterator(data()); # endif } _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return iterator(data() + size()); @@ -423,7 +423,7 @@ public: using const_pointer = const _Tp*; using reference = _Tp&; using const_reference = const _Tp&; -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN using iterator = __bounded_iter; # else using iterator = __wrap_iter; @@ -548,14 +548,14 @@ public: // [span.iter], span iterator support _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN return std::__make_bounded_iter(data(), data(), data() + size()); # else return iterator(data()); # endif } _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return iterator(data() + size()); diff --git a/libcxx/include/string_view b/libcxx/include/string_view index 861187c0640e1..cad0e12538d04 100644 --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -287,7 +287,7 @@ public: using const_pointer = const _CharT*; using reference = _CharT&; using const_reference = const _CharT&; -# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS) +# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW) using const_iterator = __bounded_iter; # elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW) using const_iterator = __wrap_iter; @@ -365,7 +365,7 @@ public: _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); } _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW return std::__make_bounded_iter(data(), data(), data() + size()); # else return const_iterator(__data_); @@ -373,7 +373,7 @@ public: } _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { -# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return const_iterator(__data_ + __size_); diff --git a/libcxx/test/libcxx/bounded-iterator-macro.compile.pass.cpp b/libcxx/test/libcxx/bounded-iterator-macro.compile.pass.cpp new file mode 100644 index 0000000000000..20e23d90b6814 --- /dev/null +++ b/libcxx/test/libcxx/bounded-iterator-macro.compile.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// This test ensures that setting _LIBCPP_ABI_BOUNDED_ITERATORS enabled bounded +// iterators in std::span and std::string_view, for historical reasons. + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ABI_BOUNDED_ITERATORS +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + +#include + +#ifndef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN +# error _LIBCPP_ABI_BOUNDED_ITERATORS should enable bounded iterators in std::span +#endif + +#ifndef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW +# error _LIBCPP_ABI_BOUNDED_ITERATORS should enable bounded iterators in std::string_view +#endif diff --git a/libcxx/test/libcxx/containers/views/views.span/assert.iterator-indexing.pass.cpp b/libcxx/test/libcxx/containers/views/views.span/assert.iterator-indexing.pass.cpp index d4dacb1f2f1c7..1e4cfd3dcc096 100644 --- a/libcxx/test/libcxx/containers/views/views.span/assert.iterator-indexing.pass.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/assert.iterator-indexing.pass.cpp @@ -9,7 +9,7 @@ // Make sure that std::span's iterators check for OOB accesses when the debug mode is enabled. -// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators +// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-span // UNSUPPORTED: libcpp-hardening-mode=none #include diff --git a/libcxx/test/libcxx/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp b/libcxx/test/libcxx/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp index 5043a88cbc3da..c9eec9cbee30b 100644 --- a/libcxx/test/libcxx/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp +++ b/libcxx/test/libcxx/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp @@ -8,7 +8,7 @@ // Make sure that std::string_view's iterators check for OOB accesses when the debug mode is enabled. -// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators +// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-string-view // UNSUPPORTED: libcpp-hardening-mode=none #include diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py index 74746e37d3bc4..f5778fb78a898 100644 --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -365,8 +365,9 @@ def _mingwSupportsModules(cfg): macros = { "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime", "_LIBCPP_ABI_VERSION": "libcpp-abi-version", - "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators", "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string", + "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING_VIEW": "libcpp-has-abi-bounded-iterators-in-string-view", + "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_SPAN": "libcpp-has-abi-bounded-iterators-in-span", "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector", "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array", "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr",