Skip to content

[libc++] Introduce _LIBCPP_ABI_BOUNDED_ITERATORS_IN_{STRING_VIEW,SPAN} #143172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions libcxx/docs/ABIGuarantees.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <hardening>` for more details.

Expand Down
26 changes: 16 additions & 10 deletions libcxx/docs/Hardening.rst
Original file line number Diff line number Diff line change
Expand Up @@ -314,30 +314,36 @@ 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``.

- ``_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<bool>``.

ABI impact: changes the iterator type of ``vector`` (except ``vector<bool>``).
Expand Down
4 changes: 4 additions & 0 deletions libcxx/docs/ReleaseNotes/21.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------

Expand Down
9 changes: 9 additions & 0 deletions libcxx/include/__configuration/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<T[]>, 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.
Expand Down
12 changes: 6 additions & 6 deletions libcxx/include/span
Original file line number Diff line number Diff line change
Expand Up @@ -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<pointer>;
# else
using iterator = __wrap_iter<pointer>;
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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<pointer>;
# else
using iterator = __wrap_iter<pointer>;
Expand Down Expand Up @@ -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());
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/string_view
Original file line number Diff line number Diff line change
Expand Up @@ -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<const_pointer>;
# elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW)
using const_iterator = __wrap_iter<const_pointer>;
Expand Down Expand Up @@ -365,15 +365,15 @@ 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_);
# endif
}

_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_);
Expand Down
23 changes: 23 additions & 0 deletions libcxx/test/libcxx/bounded-iterator-macro.compile.pass.cpp
Original file line number Diff line number Diff line change
@@ -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 <version>

#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
Original file line number Diff line number Diff line change
Expand Up @@ -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 <span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <iterator>
Expand Down
3 changes: 2 additions & 1 deletion libcxx/utils/libcxx/test/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading