[libcxx-commits] [libcxx] [libc++] Use __is_pointer_in_range for char_traits checks (PR #72643)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Nov 19 07:49:30 PST 2023


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/72643

>From c159a8757a8cdaf8b44c9470ad4a2711ec7ee545 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 17 Nov 2023 13:23:39 +0100
Subject: [PATCH] [libc++] Use __is_pointer_in_range for char_traits checks

---
 libcxx/include/__string/char_traits.h | 51 ++++++++++++---------------
 1 file changed, 23 insertions(+), 28 deletions(-)

diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h
index ca9867c39067d5d..5f76a644036ba50 100644
--- a/libcxx/include/__string/char_traits.h
+++ b/libcxx/include/__string/char_traits.h
@@ -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>
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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



More information about the libcxx-commits mailing list