Skip to content

Commit 33af68a

Browse files
authored
[libc++] Add a few _LIBCPP_ASSERT_INTERNALs to make sure internal invariants are kept (#114575)
This can make it significanly easier to find bugs when working on string.
1 parent a07b422 commit 33af68a

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

libcxx/include/__utility/is_pointer_in_range.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ __is_pointer_in_range(const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
5757
reinterpret_cast<const char*>(__ptr) < reinterpret_cast<const char*>(__end);
5858
}
5959

60+
template <class _Tp, class _Up>
61+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
62+
__is_overlapping_range(const _Tp* __begin, const _Tp* __end, const _Up* __begin2) {
63+
auto __size = __end - __begin;
64+
auto __end2 = __begin2 + __size;
65+
return std::__is_pointer_in_range(__begin, __end, __begin2) || std::__is_pointer_in_range(__begin2, __end2, __begin);
66+
}
67+
6068
_LIBCPP_END_NAMESPACE_STD
6169

6270
#endif // _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H

libcxx/include/string

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,9 @@ private:
19121912
#ifndef _LIBCPP_CXX03_LANG
19131913
if constexpr (__libcpp_is_contiguous_iterator<_ForwardIter>::value &&
19141914
is_same<value_type, __iter_value_type<_ForwardIter>>::value && is_same<_ForwardIter, _Sent>::value) {
1915+
_LIBCPP_ASSERT_INTERNAL(
1916+
!std::__is_overlapping_range(std::__to_address(__first), std::__to_address(__last), __dest),
1917+
"__copy_non_overlapping_range called with an overlapping range!");
19151918
traits_type::copy(__dest, std::__to_address(__first), __last - __first);
19161919
return __dest + (__last - __first);
19171920
}
@@ -1966,9 +1969,12 @@ private:
19661969
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_size(size_type __s) _NOEXCEPT {
19671970
__rep_.__l.__size_ = __s;
19681971
}
1972+
19691973
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_size() const _NOEXCEPT {
1974+
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long size");
19701975
return __rep_.__l.__size_;
19711976
}
1977+
19721978
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_size(size_type __s) _NOEXCEPT {
19731979
if (__is_long())
19741980
__set_long_size(__s);
@@ -1977,11 +1983,13 @@ private:
19771983
}
19781984

19791985
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_long_cap(size_type __s) _NOEXCEPT {
1986+
_LIBCPP_ASSERT_INTERNAL(!__fits_in_sso(__s), "Long capacity should always be larger than the SSO");
19801987
__rep_.__l.__cap_ = __s / __endian_factor;
19811988
__rep_.__l.__is_long_ = true;
19821989
}
19831990

19841991
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __get_long_cap() const _NOEXCEPT {
1992+
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long capacity");
19851993
return __rep_.__l.__cap_ * __endian_factor;
19861994
}
19871995

@@ -1990,10 +1998,12 @@ private:
19901998
}
19911999

19922000
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __get_long_pointer() _NOEXCEPT {
2001+
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
19932002
return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
19942003
}
19952004

19962005
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_pointer __get_long_pointer() const _NOEXCEPT {
2006+
_LIBCPP_ASSERT_INTERNAL(__rep_.__l.__is_long_, "String has to be long when trying to get the long pointer");
19972007
return _LIBCPP_ASAN_VOLATILE_WRAPPER(__rep_.__l.__data_);
19982008
}
19992009

@@ -2137,6 +2147,7 @@ private:
21372147
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string& __assign_no_alias(const value_type* __s, size_type __n);
21382148

21392149
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __erase_to_end(size_type __pos) {
2150+
_LIBCPP_ASSERT_INTERNAL(__pos <= capacity(), "Trying to erase at position outside the strings capacity!");
21402151
__null_terminate_at(std::__to_address(__get_pointer()), __pos);
21412152
}
21422153

0 commit comments

Comments
 (0)