Skip to content

Commit

Permalink
[libc++] Use __is_pointer_in_range for char_traits checks (llvm#72643)
Browse files Browse the repository at this point in the history
This allows us to also check the constraints during constant evaluation.
  • Loading branch information
philnik777 authored and sr-tream committed Nov 20, 2023
1 parent b046a58 commit d2b61b7
Showing 1 changed file with 23 additions and 28 deletions.
51 changes: 23 additions & 28 deletions libcxx/include/__string/char_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <__iterator/iterator_traits.h>
#include <__string/constexpr_c_functions.h>
#include <__type_traits/is_constant_evaluated.h>
#include <__utility/is_pointer_in_range.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
Expand Down Expand Up @@ -142,14 +143,12 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha
_LIBCPP_INLINE_VISIBILITY
static _LIBCPP_CONSTEXPR_SINCE_CXX20
char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) {
if (!__libcpp_is_constant_evaluated()) {
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
__s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
}
char_type* __r = __s1;
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
return __r;
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
"char_traits::copy: source and destination ranges overlap");
char_type* __r = __s1;
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
return __r;
}
_LIBCPP_INLINE_VISIBILITY
static _LIBCPP_CONSTEXPR_SINCE_CXX20
Expand Down Expand Up @@ -238,11 +237,10 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char>

static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
if (!__libcpp_is_constant_evaluated())
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
__s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
std::copy_n(__s2, __n, __s1);
return __s1;
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
"char_traits::copy: source and destination ranges overlap");
std::copy_n(__s2, __n, __s1);
return __s1;
}

static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
Expand Down Expand Up @@ -310,11 +308,10 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>

static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
if (!__libcpp_is_constant_evaluated())
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
__s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range");
std::copy_n(__s2, __n, __s1);
return __s1;
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
"char_traits::copy: source and destination ranges overlap");
std::copy_n(__s2, __n, __s1);
return __s1;
}

static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
Expand Down Expand Up @@ -375,11 +372,10 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>

static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
if (!__libcpp_is_constant_evaluated())
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
std::copy_n(__s2, __n, __s1);
return __s1;
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
"char_traits::copy: source and destination ranges overlap");
std::copy_n(__s2, __n, __s1);
return __s1;
}

static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
Expand Down Expand Up @@ -460,11 +456,10 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>

_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
if (!__libcpp_is_constant_evaluated())
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(
__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
std::copy_n(__s2, __n, __s1);
return __s1;
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
"char_traits::copy: source and destination ranges overlap");
std::copy_n(__s2, __n, __s1);
return __s1;
}

_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
Expand Down

0 comments on commit d2b61b7

Please sign in to comment.