In file included from /mnt/gcc.bin/include/c++/17.0.0/vector:67, from ./gcc/testsuite/g++.dg/torture/pr118521.C:5: In function ‘_ForwardIterator
std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = char*; _Size = long unsigned int; _Tp = char]’,
inlined from ‘constexpr _ForwardIteratorstd::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, allocator<_Tp>&) [with _ForwardIterator = char*; _Size = long unsigned int; _Tp = char; _Tp2 = char]’ at /mnt/gcc.bin/include/c++/17.0.0/bits/stl_uninitialized.h:778:39,
inlined from ‘constexpr void std::vector<_Tp,_Alloc>::_M_fill_append(size_type, const value_type&) [with _Tp = char; _Alloc = std::allocator<char>]’ at /mnt/gcc.bin/include/c++/17.0.0/bits/vector.tcc:776:36,
inlined from ‘constexpr void std::vector<_Tp,_Alloc>::_M_fill_insert(iterator, size_type, const value_type&) [with _Tp = char; _Alloc = std::allocator<char>]’ at /mnt/gcc.bin/include/c++/17.0.0/bits/vector.tcc:668:20,
inlined from ‘constexpr std::vector<_Tp, _Alloc>::iteratorstd::vector<_Tp, _Alloc>::insert(const_iterator, size_type, const value_type&) [with _Tp = char; _Alloc = std::allocator<char>]’ at /mnt/gcc.bin/include/c++/17.0.0/bits/stl_vector.h:1565:16,
inlined from ‘void foo()’ at./gcc/testsuite/g++.dg/torture/pr118521.C:12:11:
/mnt/gcc.bin/include/c++/17.0.0/bits/stl_uninitialized.h:577:39:
warning: ‘void* __builtin_memset(void*, int, long unsigned int)’ writing 2 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
577 | __builtin_memset(__dest, (unsigned
char)__x, __n);
|> > I think it's a victim of an existing (and very annoying) misdetection of memory overwrites (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125187). It's not directly related to my patch (which optimizes moving a range, not filling it), but my patch changes the detection logic causing gcc to think the region is of size 0 (where it should be 4). Yes, these middle-end warnings are a plague, but I don't see why your patch (which I pushed yesterday) changes the __uninitialized_fill_n_a() path which uses memset. Your patch only affects the uninitialized_copy() path which uses memcpy.
My guess is that the patch disturbed the analysis of the reallocation path by simplifying it to memcpy. The simplification allowed the faulty analysis to come to the wrong conclusion; previously the code was too complicated.
I also think it's a regression compared to when I wrote the patch, since I think I ran the entire test suite. If so I'll bisect to find the offender.