[libcxx-commits] [libcxx] 795a47f - Suppress a redundant hardening check in basic_string_view::substr (#91804)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 23 12:27:52 PDT 2024
Author: David Benjamin
Date: 2024-07-23T12:27:49-07:00
New Revision: 795a47fb66b7479f6da4f8cdfc9f83ea5d654a55
URL: https://github.com/llvm/llvm-project/commit/795a47fb66b7479f6da4f8cdfc9f83ea5d654a55
DIFF: https://github.com/llvm/llvm-project/commit/795a47fb66b7479f6da4f8cdfc9f83ea5d654a55.diff
LOG: Suppress a redundant hardening check in basic_string_view::substr (#91804)
Fixes #91634.
This could alternatively be done with an _LIBCPP_ASSUME, after
https://github.com/llvm/llvm-project/pull/91801 lands, but would also
require https://github.com/llvm/llvm-project/issues/91619 be fixed
first. Given the dependencies, it seemed simplest to just make a private
ctor.
Added:
Modified:
libcxx/include/string_view
Removed:
################################################################################
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 72dbf0bfa8e54..2a03ee99e9ab5 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -448,8 +448,11 @@ public:
}
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view substr(size_type __pos = 0, size_type __n = npos) const {
+ // Use the `__assume_valid` form of the constructor to avoid an unnecessary check. Any substring of a view is a
+ // valid view. In particular, `size()` is known to be smaller than `numeric_limits<
diff erence_type>::max()`, so the
+ // new size is also smaller. See also https://github.com/llvm/llvm-project/issues/91634.
return __pos > size() ? (__throw_out_of_range("string_view::substr"), basic_string_view())
- : basic_string_view(data() + __pos, std::min(__n, size() - __pos));
+ : basic_string_view(__assume_valid(), data() + __pos, std::min(__n, size() - __pos));
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
@@ -674,6 +677,16 @@ public:
#endif
private:
+ struct __assume_valid {};
+
+ // This is the same as the pointer and length constructor, but without the additional hardening checks. It is intended
+ // for use within the class, when the class invariants already guarantee the resulting object is valid. The compiler
+ // usually cannot eliminate the redundant checks because it does not know class invariants.
+ _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
+ basic_string_view(__assume_valid, const _CharT* __s, size_type __len) _NOEXCEPT
+ : __data_(__s),
+ __size_(__len) {}
+
const value_type* __data_;
size_type __size_;
};
More information about the libcxx-commits
mailing list