[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