]> 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>
Thu, 25 Nov 2021 20:03:13 +0000 (20:03 +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.

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

index c8c4d0329837a66985222380f2312af5f6e15b9a..9929e5e828b8b83e79fe43d383cc51f64635e80a 100644 (file)
@@ -527,17 +527,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 6a015d34a8922e5f3b07b59c765323b3b234c807..1d1e1c104d44e9d96fbe10e9bf541a7d2d9355bf 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
 }