https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117983

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2025-03-28
          Component|c++                         |libstdc++
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |redi at gcc dot gnu.org

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> That is the preprocessed source from GCC 14 fails even when compiled with
> GCC 15.

It doesn't warn on trunk since r15-7683-g0d590d21586edb which was:

Use nonnull_if_nonzero attribute rather than nonnull on various builtins
[PR117023]


But the libstdc++ change that fixed it was r15-4473-g3abe751ea86e34:

libstdc++: Refactor std::uninitialized_{copy,fill,fill_n} algos [PR68350]


That is not suitable for a backport though.

I guessed that the part that made a difference is that the new
uninitialized_copy code includes:

+         ptrdiff_t __n = __last - __first;
+         if (__n > 0) [[__likely__]]
+           {
+             using _ValT = typename remove_pointer<_Src>::type;
+             __builtin_memcpy(std::__niter_base(__result),
+                              std::__niter_base(__first),
+                              __n * sizeof(_ValT));
+             __result += __n;
+           }

The __n > 0 check means the compiler knows that size_t(last - first) is not a
huge positive number, so I tried this minimal change to
vector::_M_range_insert:

--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -1002,6 +1002,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                // reachable.
                pointer __old_start = this->_M_impl._M_start;
                pointer __old_finish = this->_M_impl._M_finish;
+               if ((__old_finish - __old_start) < 0)
+                 __builtin_unreachable();

                const size_type __len =
                  _M_check_len(__n, "vector::_M_range_insert");

And indeed it fixes this warning.

Reply via email to