[libcxx-commits] [libcxx] Suppress a redundant hardening check in basic_string_view::substr (PR #91804)
David Benjamin via libcxx-commits
libcxx-commits at lists.llvm.org
Fri May 10 13:33:45 PDT 2024
https://github.com/davidben created https://github.com/llvm/llvm-project/pull/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.
>From f71a3d95657673fa0353b955dc20dca000c16ea7 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben at google.com>
Date: Fri, 10 May 2024 16:31:11 -0400
Subject: [PATCH] Suppress a redundant hardening check in
basic_string_view::substr
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.
---
libcxx/include/string_view | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 5c4bec742bafa..2c9703cedfd2a 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -449,8 +449,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<difference_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(data() + __pos, std::min(__n, size() - __pos), __assume_valid{});
}
_LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
@@ -675,6 +678,16 @@ public:
#endif
private:
+ struct __assume_valid {};
+
+ // This is the same as the pointer and length constructor, but it does not include additionally hardening checks. It
+ // is intended for use within the class, when the class invariants already imply the resulting object is valid. The
+ // compiler usually cannot apply this optimization itself, because it does not know class invariants.
+ _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
+ basic_string_view(const _CharT* __s, size_type __len, __assume_valid) _NOEXCEPT
+ : __data_(__s),
+ __size_(__len) {}
+
const value_type* __data_;
size_type __size_;
};
More information about the libcxx-commits
mailing list