https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104789
--- Comment #9 from Martin Sebor <msebor at gcc dot gnu.org> --- A much simplified test case that reproduces the same warning (with both GCC 12 and 11) is below. The underlying problem is that although GCC does have a way to represent simple disjoint ranges of variable values, it's not used here, and even if it were, very little code makes uses of this representation beyond a single contiguous range (or, at most, a converse of it). Even the disjoint representation isn't sufficiently flexible to capture arbitrarily complex ranges (capturing those in their full generality would require a constraint solver). $ cat z.c && gcc -O3 -S -Wall z.c char a[8]; void f (unsigned n) { unsigned i = 0; for (unsigned j = 0; i != n; ++j) i += 2; if (i > 7) return; while (i % 4) a[i++] = 0; } z.c: In function ‘f’: z.c:14:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 14 | a[i++] = 0; | ~~~~~~~^~~ z.c:1:6: note: at offset 8 into destination object ‘a’ of size 8 1 | char a[8]; | ^ The warning can be avoided (and the emitted object code improved) by changing the while loop like so: while (i % 4) { if (i > 7) __builtin_unreachable (); a[i++] = 0; } The same suppression works in the test case in comment #7 but GCC then issues another warning, this one pointing out that an element of the header array is used uninitialized. That warning looks valid to me: /x86_64-pc-linux-gnu/bits/c++allocator.h:33, from /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/allocator.h:46, from /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/vector:61, from pr104789.C:2: In member function ‘void std::__new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = unsigned char; _Args = {const unsigned char&}; _Tp = unsigned char]’, inlined from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(allocator_type&, _Up*, _Args&& ...) [with _Up = unsigned char; _Args = {const unsigned char&}; _Tp = unsigned char]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/alloc_traits.h:516:17, inlined from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_vector.h:1280:30, inlined from ‘void commit_temp_packets()’ at pr104789.C:37:17: /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/new_allocator.h:175:11: warning: ‘header’ may be used uninitialized [-Wmaybe-uninitialized] 175 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr104789.C: In function ‘void commit_temp_packets()’: pr104789.C:10:17: note: ‘header’ declared here 10 | uint8_t header[8]; | ^~~~~~