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.