]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Do not use memset in constexpr calls to ranges::fill_n [PR101608]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 24 Nov 2021 13:17:54 +0000 (13:17 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Fri, 26 Nov 2021 12:50:38 +0000 (12:50 +0000)
libstdc++-v3/ChangeLog:

PR libstdc++/101608
* include/bits/ranges_algobase.h (__fill_n_fn): Check for
constant evaluation before using memset.
* testsuite/25_algorithms/fill_n/constrained.cc: Check
byte-sized values as well.

(cherry picked from commit 82c3657dd74896b39937bb0a2aaeba9b8ca105fd)

libstdc++-v3/include/bits/ranges_algobase.h
libstdc++-v3/testsuite/25_algorithms/fill_n/constrained.cc

index aef80a385865a01a8664bd76efa60d5f0f2366cc..2fb558918f8324e0c39f4cfdc3feab8f3c4a1114 100644 (file)
@@ -526,17 +526,25 @@ namespace ranges
        if (__n <= 0)
          return __first;
 
-       // TODO: Generalize this optimization to contiguous iterators.
-       if constexpr (is_pointer_v<_Out>
-                     // Note that __is_byte already implies !is_volatile.
-                     && __is_byte<remove_pointer_t<_Out>>::__value
-                     && integral<_Tp>)
-         {
-           __builtin_memset(__first, static_cast<unsigned char>(__value), __n);
-           return __first + __n;
-         }
-       else if constexpr (is_scalar_v<_Tp>)
+       if constexpr (is_scalar_v<_Tp>)
          {
+           // TODO: Generalize this optimization to contiguous iterators.
+           if constexpr (is_pointer_v<_Out>
+                         // Note that __is_byte already implies !is_volatile.
+                         && __is_byte<remove_pointer_t<_Out>>::__value
+                         && integral<_Tp>)
+             {
+#ifdef __cpp_lib_is_constant_evaluated
+               if (!std::is_constant_evaluated())
+#endif
+                 {
+                   __builtin_memset(__first,
+                                    static_cast<unsigned char>(__value),
+                                    __n);
+                   return __first + __n;
+                 }
+             }
+
            const auto __tmp = __value;
            for (; __n > 0; --__n, (void)++__first)
              *__first = __tmp;
index e9ce8e8fb0aed9ce2aac054cc480b025acc94cd7..09d3bd376309acea2b1b2bcf82b8fd1e7cf52f8b 100644 (file)
@@ -73,11 +73,12 @@ test01()
     }
 }
 
+template<typename T>
 constexpr bool
 test02()
 {
   bool ok = true;
-  int x[6] = { 1, 2, 3, 4, 5, 6 };
+  T x[6] = { 1, 2, 3, 4, 5, 6 };
   const int y[6] = { 1, 2, 3, 4, 5, 6 };
   const int z[6] = { 17, 17, 17, 4, 5, 6 };
 
@@ -94,5 +95,6 @@ int
 main()
 {
   test01();
-  static_assert(test02());
+  static_assert(test02<int>());
+  static_assert(test02<unsigned char>()); // PR libstdc++/101608
 }