[libcxx-commits] [libcxx] [libc++] Add a few _LIBCPP_ASSERT_INTERNALs to make sure internal invariants are kept (PR #114575)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Nov 1 10:06:40 PDT 2024
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/114575
This can make it significanly easier to find bugs when working on string.
>From 28ce387e3e928973db865511accfb356facfddc4 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 1 Nov 2024 17:53:09 +0100
Subject: [PATCH] [libc++] Add a few _LIBCPP_ASSERT_INTERNALs to make sure
internal invariants are kept
---
libcxx/include/__utility/is_pointer_in_range.h | 6 ++++++
libcxx/include/string | 11 +++++++++++
2 files changed, 17 insertions(+)
diff --git a/libcxx/include/__utility/is_pointer_in_range.h b/libcxx/include/__utility/is_pointer_in_range.h
index 4130b4ac707000..efee11bfe55519 100644
--- a/libcxx/include/__utility/is_pointer_in_range.h
+++ b/libcxx/include/__utility/is_pointer_in_range.h
@@ -57,6 +57,12 @@ __is_pointer_in_range(const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
reinterpret_cast<const char*>(__ptr) < reinterpret_cast<const char*>(__end);
}
+template <class _Tp, class _Up>
+_LIBCPP_CONSTEXPR_SINCE_CXX14 bool __is_overlapping_range(const _Tp* __begin, const _Tp* __end, const _Up* __begin2) {
+ return std::__is_pointer_in_range(__begin, __end, __begin2) ||
+ std::__is_pointer_in_range(__begin2, __begin2 + (__end - __begin), __begin);
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H
diff --git a/libcxx/include/string b/libcxx/include/string
index 4b5017f5e7753f..20e44eaca2ac7a 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1912,6 +1912,9 @@ private:
#ifndef _LIBCPP_CXX03_LANG
if constexpr (__libcpp_is_contiguous_iterator<_ForwardIter>::value &&
is_same<value_type, __iter_value_type<_ForwardIter>>::value && is_same<_ForwardIter, _Sent>::value) {
+ _LIBCPP_ASSERT_INTERNAL(
+ !std::__is_overlapping_range(std::__to_address(__first), std::__to_address(__last), __dest),
+ "__copy_non_overlapping_range called with an overlapping range!");
traits_type::copy(__dest, std::__to_address(__first), __last - __first);
return __dest + (__last - __first);
}
@@ -1966,9 +1969,12 @@ private:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_size(size_type __s) _NOEXCEPT {
__rep_.__l.__size_ = __s;
}
+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_size() const _NOEXCEPT {
+ _LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long size");
return __rep_.__l.__size_;
}
+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_size(size_type __s) _NOEXCEPT {
if (__is_long())
__set_long_size(__s);
@@ -1977,11 +1983,13 @@ private:
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_cap(size_type __s) _NOEXCEPT {
+ _LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__s), "Long capacity should always be larger than the SSO");
__rep_.__l.__cap_ = __s / __endian_factor;
__rep_.__l.__is_long_ = true;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT {
+ _LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long capacity");
return __rep_.__l.__cap_ * __endian_factor;
}
@@ -1990,10 +1998,12 @@ private:
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_long_pointer() _NOEXCEPT {
+ _LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_long_pointer() const _NOEXCEPT {
+ _LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
}
@@ -2137,6 +2147,7 @@ private:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) {
+ _LIBCPP_ASSERT_INTERNAL(__pos <= capacity(), "Trying to erase at position outside the strings capacity!");
__null_terminate_at(std::__to_address(__get_pointer()), __pos);
}
More information about the libcxx-commits
mailing list